1 /*
2    BAREOS® - Backup Archiving REcovery Open Sourced
3 
4    Copyright (C) 2002-2012 Free Software Foundation Europe e.V.
5    Copyright (C) 2011-2012 Planets Communications B.V.
6    Copyright (C) 2013-2021 Bareos GmbH & Co. KG
7 
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version three of the GNU Affero General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12 
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    Affero General Public License for more details.
17 
18    You should have received a copy of the GNU Affero General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22 */
23 /*
24  * Kern Sibbald, August MMII
25  */
26 /**
27  * @file
28  * Routines for handling mounting tapes for reading and for writing.
29  */
30 
31 #include "include/bareos.h" /* pull in global headers */
32 #include "stored/stored.h"  /* pull in Storage Daemon headers */
33 #include "stored/acquire.h"
34 #include "stored/autochanger.h"
35 #include "stored/device_control_record.h"
36 #include "stored/jcr_private.h"
37 #include "stored/label.h"
38 #include "lib/edit.h"
39 #include "include/jcr.h"
40 #include "lib/bsock.h"
41 
42 namespace storagedaemon {
43 
44 static pthread_mutex_t mount_mutex = PTHREAD_MUTEX_INITIALIZER;
45 
46 enum
47 {
48   try_next_vol = 1,
49   try_read_vol,
50   try_error,
51   try_default
52 };
53 
54 enum
55 {
56   check_next_vol = 1,
57   check_ok,
58   check_read_vol,
59   check_error
60 };
61 
62 /**
63  * If release is set, we rewind the current volume,
64  * which we no longer want, and ask the user (console)
65  * to mount the next volume.
66  *
67  *  Continue trying until we get it, and then ensure
68  *  that we can write on it.
69  *
70  * This routine returns a 0 only if it is REALLY
71  *  impossible to get the requested Volume.
72  *
73  * This routine is entered with the device blocked, but not
74  *   locked.
75  *
76  */
MountNextWriteVolume()77 bool DeviceControlRecord::MountNextWriteVolume()
78 {
79   int retry = 0;
80   bool ask = false, recycle, autochanger;
81   DeviceMode mode;
82   DeviceControlRecord* dcr = this;
83 
84   Dmsg2(150, "Enter mount_next_volume(release=%d) dev=%s\n", dev->MustUnload(),
85         dev->print_name());
86 
87   InitDeviceWaitTimers(dcr);
88 
89   P(mount_mutex);
90 
91   /*
92    * Attempt to mount the next volume. If something non-fatal goes
93    *  wrong, we come back here to re-try (new op messages, re-read
94    *  Volume, ...)
95    */
96 
97 mount_next_vol:
98   Dmsg1(150, "mount_next_vol retry=%d\n", retry);
99   /*
100    * Ignore retry if this is poll request
101    */
102   if (retry++ > 4) {
103     /*
104      * Last ditch effort before giving up, force operator to respond
105      */
106     VolCatInfo.Slot = 0;
107     V(mount_mutex);
108     if (!dcr->DirAskSysopToMountVolume(ST_APPENDREADY)) {
109       Jmsg(jcr, M_FATAL, 0, _("Too many errors trying to mount device %s.\n"),
110            dev->print_name());
111       goto no_lock_bail_out;
112     }
113     P(mount_mutex);
114     Dmsg1(150, "Continue after dir_ask_sysop_to_mount. must_load=%d\n",
115           dev->must_load());
116   }
117 
118   if (JobCanceled(jcr)) {
119     Jmsg(jcr, M_FATAL, 0, _("Job %d canceled.\n"), jcr->JobId);
120     goto bail_out;
121   }
122   recycle = false;
123 
124   if (dev->MustUnload()) { ask = true; /* ask operator to mount tape */ }
125 
126   DoUnload();
127   DoSwapping(true /*IsWriting*/);
128   DoLoad(true /*IsWriting*/);
129 
130   if (!find_a_volume()) { goto bail_out; }
131 
132   if (JobCanceled(jcr)) { goto bail_out; }
133 
134   Dmsg2(150, "After find_next_append. Vol=%s Slot=%d\n", getVolCatName(),
135         VolCatInfo.Slot);
136 
137   /*
138    * Get next volume and ready it for append
139    * This code ensures that the device is ready for
140    * writing. We start from the assumption that there
141    * may not be a tape mounted.
142    *
143    * If the device is a file, we create the output
144    * file. If it is a tape, we check the volume name
145    * and move the tape to the end of data.
146    */
147   dcr->setVolCatInfo(false); /* out of date when Vols unlocked */
148 
149   /*
150    * See if this is a retry of the mounting of the next volume.
151    * If the device is already open close it first as otherwise we could
152    * potentially write to an already open device a new volume label.
153    * This is only interesting for non tape devices.
154    */
155   if (!dev->IsTape()) {
156     if (retry && dev->IsOpen()) { dev->close(dcr); }
157   }
158 
159   switch (AutoloadDevice(dcr, true /* writing */, NULL)) {
160     case -3:
161       Dmsg0(100, "Wait after a unsuccessful tape load (empty slot).\n");
162       Jmsg0(jcr, M_WARNING, 0,
163             "Wait after a unsuccessful tape load (empty slot).\n");
164       Bmicrosleep(1, 0);
165       dev->VolHdr.VolumeName[0] = 0;
166       dev->vol = 0; /* do not free volume here because in this case
167                      * it is still on the vol_list chain for another job */
168       goto mount_next_vol;
169       break;
170     case -2:
171     case -1:
172       /*
173        * -1 => error on autochanger
174        */
175       autochanger = false;
176       VolCatInfo.Slot = 0;
177       ask = retry >= 2;
178       break;
179     case 0:
180       /*
181        * 0 => failure (no changer available)
182        */
183       autochanger = false;
184       VolCatInfo.Slot = 0;
185 
186       /*
187        * If the VolCatInfo.InChanger flag is not set we are trying to use a
188        * volume that is not in the autochanger so that means we need to ask the
189        * operator to mount it.
190        */
191       if (dev->AttachedToAutochanger() && !VolCatInfo.InChanger) {
192         ask = true;
193       } else {
194         ask = retry >= 2;
195       }
196       break;
197     default:
198       /*
199        * Success
200        */
201       autochanger = true;
202       ask = false;
203       break;
204   }
205   Dmsg1(150, "autoLoadDev returns %d\n", autochanger);
206 
207   /*
208    * If we autochanged to correct Volume or (we have not just
209    * released the Volume AND we can automount) we go ahead
210    * and read the label. If there is no tape in the drive,
211    * we will fail, recurse and ask the operator the next time.
212    */
213   if (!dev->MustUnload() && dev->IsTape() && dev->HasCap(CAP_AUTOMOUNT)) {
214     Dmsg0(250, "(1)Ask=0\n");
215     ask = false; /* don't ask SYSOP this time */
216   }
217 
218   /*
219    * Don't ask if not removable
220    */
221   if (!dev->IsRemovable()) {
222     Dmsg0(250, "(2)Ask=0\n");
223     ask = false;
224   }
225   Dmsg2(250, "Ask=%d autochanger=%d\n", ask, autochanger);
226 
227   if (ask) {
228     V(mount_mutex);
229     dcr->setVolCatInfo(false); /* out of date when Vols unlocked */
230     if (!dcr->DirAskSysopToMountVolume(ST_APPENDREADY)) {
231       Dmsg0(150, "Error return ask_sysop ...\n");
232       goto no_lock_bail_out;
233     }
234     P(mount_mutex);
235   }
236 
237   if (JobCanceled(jcr)) { goto bail_out; }
238 
239   Dmsg3(150, "want vol=%s devvol=%s dev=%s\n", VolumeName,
240         dev->VolHdr.VolumeName, dev->print_name());
241 
242   if (dev->poll && dev->HasCap(CAP_CLOSEONPOLL)) {
243     dev->close(dcr);
244     FreeVolume(dev);
245   }
246 
247   /*
248    * Ensure the device is open
249    */
250   if (dev->HasCap(CAP_STREAM)) {
251     mode = DeviceMode::OPEN_WRITE_ONLY;
252   } else {
253     mode = DeviceMode::OPEN_READ_WRITE;
254   }
255 
256   /*
257    * Try autolabel if enabled
258    */
259   if (!dev->open(dcr, mode)) {
260     TryAutolabel(false); /* try to create a new volume label */
261   }
262 
263   while (!dev->open(dcr, mode)) {
264     Dmsg1(150, "OpenDevice failed: ERR=%s\n", dev->bstrerror());
265     if (dev->IsFile() && dev->IsRemovable()) {
266       bool ok = true;
267       Dmsg0(150, "call scan_dir_for_vol\n");
268       if (ok && dev->ScanDirForVolume(dcr)) {
269         if (dev->open(dcr, mode)) { break; /* got a valid volume */ }
270       }
271     }
272     if (TryAutolabel(false) == try_read_vol) {
273       break; /* created a new volume label */
274     }
275     Jmsg3(jcr, M_WARNING, 0, _("Open device %s Volume \"%s\" failed: ERR=%s\n"),
276           dev->print_name(), dcr->VolumeName, dev->bstrerror());
277     Dmsg0(50, "SetUnload\n");
278     dev->SetUnload(); /* force ask sysop */
279     ask = true;
280     Dmsg0(150, "goto mount_next_vol\n");
281     goto mount_next_vol;
282   }
283 
284   /*
285    * Now check the volume label to make sure we have the right tape mounted
286    */
287 read_volume:
288   switch (CheckVolumeLabel(ask, autochanger)) {
289     case check_next_vol:
290       Dmsg0(50, "SetUnload\n");
291       dev->SetUnload(); /* want a different Volume */
292       Dmsg0(150, "goto mount_next_vol\n");
293       goto mount_next_vol;
294     case check_read_vol:
295       goto read_volume;
296     case check_error:
297       goto bail_out;
298     case check_ok:
299       break;
300   }
301   /*
302    * Check that volcatinfo is good
303    */
304   if (!dev->haveVolCatInfo()) {
305     Dmsg0(210, "Do not have volcatinfo\n");
306     if (!find_a_volume()) { goto mount_next_vol; }
307 
308     dev->VolCatInfo = VolCatInfo; /* structure assignment */
309 
310     /*
311      * Apply the Volume Blocksizes to device
312      */
313     dcr->VolMinBlocksize = VolCatInfo.VolMinBlocksize;
314     dcr->VolMaxBlocksize = VolCatInfo.VolMaxBlocksize;
315     Dmsg3(200,
316           "applying vol block sizes to device %s: dcr->VolMinBlocksize set to "
317           "%u, dcr->VolMaxBlocksize set to %u\n",
318           dev->print_name(), dcr->VolMinBlocksize, dcr->VolMaxBlocksize);
319 
320     /*
321      * Set the block sizes of the dcr in the device.
322      */
323     dev->SetBlocksizes(dcr);
324   }
325 
326   /*
327    * See if we have a fresh tape or a tape with data.
328    *
329    * Note, if the LabelType is PRE_LABEL, it was labeled
330    *  but never written. If so, rewrite the label but set as
331    *  VOL_LABEL.  We rewind and return the label (reconstructed)
332    *  in the block so that in the case of a new tape, data can
333    *  be appended just after the block label.  If we are writing
334    *  a second volume, the calling routine will write the label
335    *  before writing the overflow block.
336    *
337    *  If the tape is marked as Recycle, we rewrite the label.
338    */
339   recycle = bstrcmp(dev->VolCatInfo.VolCatStatus, "Recycle");
340   if (dev->VolHdr.LabelType == PRE_LABEL || recycle) {
341     if (!dcr->RewriteVolumeLabel(recycle)) {
342       MarkVolumeInError();
343       goto mount_next_vol;
344     }
345   } else {
346     /*
347      * OK, at this point, we have a valid Bareos label, but
348      * we need to position to the end of the volume, since we are
349      * just now putting it into append mode.
350      */
351     Dmsg1(
352         100,
353         "Device previously written, moving to end of data. Expect %lld bytes\n",
354         dev->VolCatInfo.VolCatBytes);
355     Jmsg(jcr, M_INFO, 0,
356          _("Volume \"%s\" previously written, moving to end of data.\n"),
357          VolumeName);
358 
359     if (!dev->eod(dcr)) {
360       Dmsg2(050, "Unable to position to end of data on device %s: ERR=%s\n",
361             dev->print_name(), dev->bstrerror());
362       Jmsg(jcr, M_ERROR, 0,
363            _("Unable to position to end of data on device %s: ERR=%s\n"),
364            dev->print_name(), dev->bstrerror());
365       MarkVolumeInError();
366       goto mount_next_vol;
367     }
368     if (!is_eod_valid()) {
369       Dmsg0(100, "goto mount_next_vol\n");
370       goto mount_next_vol;
371     }
372 
373     dev->VolCatInfo.VolCatMounts++; /* Update mounts */
374     Dmsg1(150, "update volinfo mounts=%d\n", dev->VolCatInfo.VolCatMounts);
375     if (!dcr->DirUpdateVolumeInfo(false, false)) { goto bail_out; }
376 
377     /* Return an empty block */
378     EmptyBlock(block); /* we used it for reading so set for write */
379   }
380   dev->SetAppend();
381   Dmsg1(150, "set APPEND, normal return from MountNextWriteVolume. dev=%s\n",
382         dev->print_name());
383 
384   V(mount_mutex);
385   return true;
386 
387 bail_out:
388   V(mount_mutex);
389 
390 no_lock_bail_out:
391   return false;
392 }
393 
394 /**
395  * This routine is meant to be called once the first pass
396  * to ensure that we have a candidate volume to mount.
397  * Otherwise, we ask the sysop to created one.
398  *
399  * Note, mount_mutex is already locked on entry and thus
400  * must remain locked on exit from this function.
401  */
find_a_volume()402 bool DeviceControlRecord::find_a_volume()
403 {
404   DeviceControlRecord* dcr = this;
405 
406   if (!IsSuitableVolumeMounted()) {
407     bool have_vol = false;
408 
409     /*
410      * Do we have a candidate volume?
411      */
412     if (dev->vol) {
413       bstrncpy(VolumeName, dev->vol->vol_name, sizeof(VolumeName));
414       have_vol = dcr->DirGetVolumeInfo(GET_VOL_INFO_FOR_WRITE);
415     }
416 
417     /*
418      * Get Director's idea of what tape we should have mounted, in
419      * dcr->VolCatInfo
420      */
421     if (!have_vol) {
422       Dmsg0(200, "Before DirFindNextAppendableVolume.\n");
423       while (!dcr->DirFindNextAppendableVolume()) {
424         Dmsg0(200, "not dir_find_next\n");
425         if (JobCanceled(jcr)) { return false; }
426         V(mount_mutex);
427         if (!dcr->DirAskSysopToCreateAppendableVolume()) {
428           P(mount_mutex);
429           return false;
430         }
431         P(mount_mutex);
432         if (JobCanceled(jcr)) { return false; }
433         Dmsg0(150, "Again dir_find_next_append...\n");
434       }
435     }
436   }
437 
438   if (dcr->haveVolCatInfo()) { return true; }
439 
440   return dcr->DirGetVolumeInfo(GET_VOL_INFO_FOR_WRITE);
441 }
442 
CheckVolumeLabel(bool & ask,bool & autochanger)443 int DeviceControlRecord::CheckVolumeLabel(bool& ask, bool& autochanger)
444 {
445   DeviceControlRecord* dcr = this;
446   int vol_label_status;
447 
448   /*
449    * If we are writing to a stream device, ASSUME the volume label
450    *  is correct.
451    */
452   if (dev->HasCap(CAP_STREAM)) {
453     vol_label_status = VOL_OK;
454     CreateVolumeLabel(dev, VolumeName, "Default");
455     dev->VolHdr.LabelType = PRE_LABEL;
456   } else {
457     vol_label_status = ReadDevVolumeLabel(dcr);
458   }
459   if (JobCanceled(jcr)) { goto check_bail_out; }
460 
461   Dmsg2(150, "Want dirVol=%s dirStat=%s\n", VolumeName,
462         VolCatInfo.VolCatStatus);
463 
464   /*
465    * At this point, dev->VolCatInfo has what is in the drive, if anything,
466    *          and   dcr->VolCatInfo has what the Director wants.
467    */
468   switch (vol_label_status) {
469     case VOL_OK:
470       Dmsg1(150, "Vol OK name=%s\n", dev->VolHdr.VolumeName);
471       dev->VolCatInfo = VolCatInfo; /* structure assignment */
472       break;                        /* got a Volume */
473     case VOL_NAME_ERROR: {
474       VolumeCatalogInfo dcrVolCatInfo, devVolCatInfo;
475       char saveVolumeName[MAX_NAME_LENGTH];
476 
477       Dmsg2(150, "Vol NAME Error Have=%s, want=%s\n", dev->VolHdr.VolumeName,
478             VolumeName);
479       if (dev->IsVolumeToUnload()) {
480         ask = true;
481         goto check_next_volume;
482       }
483 
484       /* If not removable, Volume is broken */
485       if (!dev->IsRemovable()) {
486         Jmsg(jcr, M_WARNING, 0, _("Volume \"%s\" not on device %s.\n"),
487              VolumeName, dev->print_name());
488         MarkVolumeInError();
489         goto check_next_volume;
490       }
491 
492       /*
493        * OK, we got a different volume mounted. First save the
494        *  requested Volume info (dcr) structure, then query if
495        *  this volume is really OK. If not, put back the desired
496        *  volume name, mark it not in changer and continue.
497        */
498       dcrVolCatInfo = VolCatInfo;      /* structure assignment */
499       devVolCatInfo = dev->VolCatInfo; /* structure assignment */
500       /* Check if this is a valid Volume in the pool */
501       bstrncpy(saveVolumeName, VolumeName, sizeof(saveVolumeName));
502       bstrncpy(VolumeName, dev->VolHdr.VolumeName, sizeof(VolumeName));
503       if (!dcr->DirGetVolumeInfo(GET_VOL_INFO_FOR_WRITE)) {
504         PoolMem vol_info_msg;
505         PmStrcpy(vol_info_msg, jcr->dir_bsock->msg); /* save error message */
506         /* Restore desired volume name, note device info out of sync */
507         /* This gets the info regardless of the Pool */
508         bstrncpy(VolumeName, dev->VolHdr.VolumeName, sizeof(VolumeName));
509         if (autochanger && !dcr->DirGetVolumeInfo(GET_VOL_INFO_FOR_READ)) {
510           /*
511            * If we get here, we know we cannot write on the Volume,
512            *  and we know that we cannot read it either, so it
513            *  is not in the autochanger.
514            */
515           mark_volume_not_inchanger();
516         }
517         dev->VolCatInfo = devVolCatInfo; /* structure assignment */
518         dev->SetUnload();                /* unload this volume */
519         Jmsg(jcr, M_WARNING, 0,
520              _("Director wanted Volume \"%s\".\n"
521                "    Current Volume \"%s\" not acceptable because:\n"
522                "    %s"),
523              dcrVolCatInfo.VolCatName, dev->VolHdr.VolumeName,
524              vol_info_msg.c_str());
525         ask = true;
526         /* Restore saved DeviceControlRecord before continuing */
527         bstrncpy(VolumeName, saveVolumeName, sizeof(VolumeName));
528         VolCatInfo = dcrVolCatInfo; /* structure assignment */
529         goto check_next_volume;
530       }
531       /*
532        * This was not the volume we expected, but it is OK with
533        * the Director, so use it.
534        */
535       Dmsg1(150, "Got new Volume name=%s\n", VolumeName);
536       dev->VolCatInfo = VolCatInfo; /* structure assignment */
537       Dmsg1(100, "Call reserve_volume=%s\n", dev->VolHdr.VolumeName);
538       if (reserve_volume(dcr, dev->VolHdr.VolumeName) == NULL) {
539         Jmsg2(jcr, M_WARNING, 0, _("Could not reserve volume %s on %s\n"),
540               dev->VolHdr.VolumeName, dev->print_name());
541         ask = true;
542         dev->setVolCatInfo(false);
543         setVolCatInfo(false);
544         goto check_next_volume;
545       }
546       break; /* got a Volume */
547     }
548     /*
549      * At this point, we assume we have a blank tape mounted.
550      */
551     case VOL_IO_ERROR:
552       /* Fall through wanted */
553     case VOL_NO_LABEL:
554       switch (TryAutolabel(true)) {
555         case try_next_vol:
556           goto check_next_volume;
557         case try_read_vol:
558           goto check_read_volume;
559         case try_error:
560           goto check_bail_out;
561         case try_default:
562           break;
563       }
564       /* NOTE! Fall-through wanted. */
565     case VOL_NO_MEDIA:
566     default:
567       Dmsg0(200, "VOL_NO_MEDIA or default.\n");
568       /* Send error message */
569       if (!dev->poll) {
570       } else {
571         Dmsg1(200, "Msg suppressed by poll: %s\n", jcr->errmsg);
572       }
573       ask = true;
574       /* Needed, so the medium can be changed */
575       if (dev->RequiresMount()) {
576         dev->close(dcr);
577         FreeVolume(dev);
578       }
579       goto check_next_volume;
580   }
581   return check_ok;
582 
583 check_next_volume:
584   dev->setVolCatInfo(false);
585   setVolCatInfo(false);
586   return check_next_vol;
587 
588 check_bail_out:
589   return check_error;
590 
591 check_read_volume:
592   return check_read_vol;
593 }
594 
IsSuitableVolumeMounted()595 bool DeviceControlRecord::IsSuitableVolumeMounted()
596 {
597   /* Volume mounted? */
598   if (dev->VolHdr.VolumeName[0] == 0 || dev->swap_dev || dev->MustUnload()) {
599     return false; /* no */
600   }
601   bstrncpy(VolumeName, dev->VolHdr.VolumeName, sizeof(VolumeName));
602   return DirGetVolumeInfo(GET_VOL_INFO_FOR_WRITE);
603 }
604 
DoUnload()605 bool DeviceControlRecord::DoUnload()
606 {
607   DeviceControlRecord* dcr = this;
608 
609   if (GeneratePluginEvent(jcr, bSdEventVolumeUnload, dcr) != bRC_OK) {
610     return false;
611   }
612 
613   if (dev->MustUnload()) {
614     Dmsg1(100, "MustUnload release %s\n", dev->print_name());
615     ReleaseVolume();
616   }
617   return true;
618 }
619 
DoLoad(bool IsWriting)620 bool DeviceControlRecord::DoLoad(bool IsWriting)
621 {
622   DeviceControlRecord* dcr = this;
623   bool retval = false;
624 
625   if (dev->must_load()) {
626     Dmsg1(100, "Must load %s\n", dev->print_name());
627     if (AutoloadDevice(dcr, IsWriting, NULL) > 0) {
628       dev->clear_load();
629       retval = true;
630     }
631   } else {
632     retval = true;
633   }
634 
635   if (GeneratePluginEvent(jcr, bSdEventVolumeLoad, dcr) != bRC_OK) {
636     retval = false;
637   }
638 
639   return retval;
640 }
641 
DoSwapping(bool IsWriting)642 void DeviceControlRecord::DoSwapping(bool IsWriting)
643 {
644   DeviceControlRecord* dcr = this;
645 
646   /*
647    * See if we are asked to swap the Volume from another device
648    *  if so, unload the other device here, and attach the
649    *  volume to our drive.
650    */
651   if (dev->swap_dev) {
652     if (dev->swap_dev->MustUnload()) {
653       if (dev->vol) { dev->swap_dev->SetSlotNumber(dev->vol->GetSlot()); }
654       Dmsg2(100, "Swap unloading slot=%d %s\n", dev->swap_dev->GetSlot(),
655             dev->swap_dev->print_name());
656       UnloadDev(dcr, dev->swap_dev);
657     }
658     if (dev->vol) {
659       dev->vol->ClearSwapping();
660       Dmsg1(100, "=== set in_use vol=%s\n", dev->vol->vol_name);
661       dev->vol->SetInUse();
662       dev->VolHdr.VolumeName[0] = 0; /* don't yet have right Volume */
663     } else {
664       Dmsg1(100, "No vol on dev=%s\n", dev->print_name());
665     }
666     if (dev->swap_dev->vol) {
667       Dmsg2(100, "Vol=%s on dev=%s\n", dev->swap_dev->vol->vol_name,
668             dev->swap_dev->print_name());
669     }
670     Dmsg2(100, "Set swap_dev=NULL for dev=%s swap_dev=%s\n", dev->print_name(),
671           dev->swap_dev->print_name());
672     dev->swap_dev = NULL;
673   } else {
674     Dmsg0(100, "No swap_dev set\n");
675   }
676 }
677 
678 /**
679  * Check if the current position on the volume corresponds to what is in the
680  * catalog.
681  */
is_eod_valid()682 bool DeviceControlRecord::is_eod_valid()
683 {
684   DeviceControlRecord* dcr = this;
685 
686   if (dev->IsTape()) {
687     /*
688      * Check if we are positioned on the tape at the same place
689      * that the database says we should be.
690      */
691     if (dev->VolCatInfo.VolCatFiles == dev->GetFile()) {
692       Jmsg(jcr, M_INFO, 0,
693            _("Ready to append to end of Volume \"%s\" at file=%d.\n"),
694            VolumeName, dev->GetFile());
695     } else if (dev->GetFile() > dev->VolCatInfo.VolCatFiles) {
696       Jmsg(jcr, M_WARNING, 0,
697            _("For Volume \"%s\":\n"
698              "The number of files mismatch! Volume=%u Catalog=%u\n"
699              "Correcting Catalog\n"),
700            VolumeName, dev->GetFile(), dev->VolCatInfo.VolCatFiles);
701       dev->VolCatInfo.VolCatFiles = dev->GetFile();
702       dev->VolCatInfo.VolCatBlocks = dev->GetBlockNum();
703       if (!dcr->DirUpdateVolumeInfo(false, true)) {
704         Jmsg(jcr, M_WARNING, 0, _("Error updating Catalog\n"));
705         MarkVolumeInError();
706         return false;
707       }
708     } else {
709       Jmsg(jcr, M_ERROR, 0,
710            _("Bareos cannot write on tape Volume \"%s\" because:\n"
711              "The number of files mismatch! Volume=%u Catalog=%u\n"),
712            VolumeName, dev->GetFile(), dev->VolCatInfo.VolCatFiles);
713       MarkVolumeInError();
714       return false;
715     }
716   } else if (dev->IsFile()) {
717     char ed1[50], ed2[50];
718 
719     boffset_t pos;
720     pos = dev->d_lseek(dcr, (boffset_t)0, SEEK_CUR);
721     if (dev->VolCatInfo.VolCatBytes == (uint64_t)pos) {
722       Jmsg(jcr, M_INFO, 0,
723            _("Ready to append to end of Volume \"%s\""
724              " size=%s\n"),
725            VolumeName, edit_uint64(dev->VolCatInfo.VolCatBytes, ed1));
726     } else if ((uint64_t)pos > dev->VolCatInfo.VolCatBytes) {
727       Jmsg(jcr, M_WARNING, 0,
728            _("For Volume \"%s\":\n"
729              "The sizes do not match! Volume=%s Catalog=%s\n"
730              "Correcting Catalog\n"),
731            VolumeName, edit_uint64(pos, ed1),
732            edit_uint64(dev->VolCatInfo.VolCatBytes, ed2));
733       dev->VolCatInfo.VolCatBytes = (uint64_t)pos;
734       dev->VolCatInfo.VolCatFiles = (uint32_t)(pos >> 32);
735       if (!dcr->DirUpdateVolumeInfo(false, true)) {
736         Jmsg(jcr, M_WARNING, 0, _("Error updating Catalog\n"));
737         MarkVolumeInError();
738         return false;
739       }
740     } else {
741       Mmsg(jcr->errmsg,
742            _("Bareos cannot write on disk Volume \"%s\" because: "
743              "The sizes do not match! Volume=%s Catalog=%s\n"),
744            VolumeName, edit_uint64(pos, ed1),
745            edit_uint64(dev->VolCatInfo.VolCatBytes, ed2));
746       Jmsg(jcr, M_ERROR, 0, jcr->errmsg);
747       Dmsg0(050, jcr->errmsg);
748       MarkVolumeInError();
749       return false;
750     }
751   } else if (dev->IsFifo() || dev->IsVtl()) {
752     return true;
753   } else {
754     Mmsg1(
755         jcr->errmsg,
756         _("Don't know how to check if EOD is valid for a device of type %d\n"),
757         dev->dev_type);
758     Jmsg(jcr, M_ERROR, 0, jcr->errmsg);
759     Dmsg0(050, jcr->errmsg);
760     return false;
761   }
762 
763   return true;
764 }
765 
766 /**
767  * If permitted, we label the device, make sure we can do
768  *   it by checking that the VolCatBytes is zero => not labeled,
769  *   once the Volume is labeled we don't want to label another
770  *   blank tape with the same name.  For disk, we go ahead and
771  *   label it anyway, because the OS insures that there is only
772  *   one Volume with that name.
773  * As noted above, at this point dcr->VolCatInfo has what
774  *   the Director wants and dev->VolCatInfo has info on the
775  *   previous tape (or nothing).
776  *
777  * Return codes are:
778  *   try_next_vol        label failed, look for another volume
779  *   try_read_vol        labeled volume, now re-read the label
780  *   try_error           hard error (catalog update)
781  *   try_default         I couldn't do anything
782  */
TryAutolabel(bool opened)783 int DeviceControlRecord::TryAutolabel(bool opened)
784 {
785   DeviceControlRecord* dcr = this;
786 
787   if (dev->poll && !dev->IsTape()) {
788     return try_default; /* if polling, don't try to create new labels */
789   }
790   /* For a tape require it to be opened and read before labeling */
791   if (!opened && dev->IsTape()) { return try_default; }
792   if (dev->HasCap(CAP_LABEL)
793       && (VolCatInfo.VolCatBytes == 0
794           || (!dev->IsTape() && bstrcmp(VolCatInfo.VolCatStatus, "Recycle")))) {
795     Dmsg0(150, "Create volume label\n");
796     /* Create a new Volume label and write it to the device */
797     if (!WriteNewVolumeLabelToDev(dcr, VolumeName, pool_name,
798                                   false /* no relabel */)) {
799       Dmsg2(150, "write_vol_label failed. vol=%s, pool=%s\n", VolumeName,
800             pool_name);
801       if (opened) { MarkVolumeInError(); }
802       return try_next_vol;
803     }
804     Dmsg0(150, "dir_update_vol_info. Set Append\n");
805     /* Copy Director's info into the device info */
806     dev->VolCatInfo = VolCatInfo;                /* structure assignment */
807     if (!dcr->DirUpdateVolumeInfo(true, true)) { /* indicate tape labeled */
808       return try_error;
809     }
810     Jmsg(dcr->jcr, M_INFO, 0, _("Labeled new Volume \"%s\" on device %s.\n"),
811          VolumeName, dev->print_name());
812     return try_read_vol; /* read label we just wrote */
813   }
814   if (!dev->HasCap(CAP_LABEL) && VolCatInfo.VolCatBytes == 0) {
815     Jmsg(jcr, M_WARNING, 0,
816          _("Device %s not configured to autolabel Volumes.\n"),
817          dev->print_name());
818   }
819   /* If not removable, Volume is broken */
820   if (!dev->IsRemovable()) {
821     Jmsg(jcr, M_WARNING, 0, _("Volume \"%s\" not on device %s.\n"), VolumeName,
822          dev->print_name());
823     MarkVolumeInError();
824     return try_next_vol;
825   }
826   return try_default;
827 }
828 
829 /**
830  * Mark volume in error in catalog
831  */
MarkVolumeInError()832 void DeviceControlRecord::MarkVolumeInError()
833 {
834   DeviceControlRecord* dcr = this;
835 
836   Jmsg(jcr, M_INFO, 0, _("Marking Volume \"%s\" in Error in Catalog.\n"),
837        VolumeName);
838   dev->VolCatInfo = VolCatInfo; /* structure assignment */
839   bstrncpy(dev->VolCatInfo.VolCatStatus, "Error",
840            sizeof(dev->VolCatInfo.VolCatStatus));
841   Dmsg0(150, "dir_update_vol_info. Set Error.\n");
842   dcr->DirUpdateVolumeInfo(false, false);
843   VolumeUnused(dcr);
844   Dmsg0(50, "SetUnload\n");
845   dev->SetUnload(); /* must get a new volume */
846 }
847 
848 /**
849  * The Volume is not in the correct slot, so mark this
850  * Volume as not being in the Changer.
851  */
mark_volume_not_inchanger()852 void DeviceControlRecord::mark_volume_not_inchanger()
853 {
854   DeviceControlRecord* dcr = this;
855 
856   Jmsg(jcr, M_ERROR, 0,
857        _("Autochanger Volume \"%s\" not found in slot %d.\n"
858          "    Setting InChanger to zero in catalog.\n"),
859        getVolCatName(), VolCatInfo.Slot);
860   dev->VolCatInfo = VolCatInfo; /* structure assignment */
861   VolCatInfo.InChanger = false;
862   dev->VolCatInfo.InChanger = false;
863   Dmsg0(400, "update vol info in mount\n");
864   dcr->DirUpdateVolumeInfo(true, false); /* set new status */
865 }
866 
867 /**
868  * Either because we are going to hang a new volume, or because
869  * of explicit user request, we release the current volume.
870  */
ReleaseVolume()871 void DeviceControlRecord::ReleaseVolume()
872 {
873   DeviceControlRecord* dcr = this;
874 
875   UnloadAutochanger(dcr, -1);
876 
877   GeneratePluginEvent(jcr, bSdEventVolumeUnload, dcr);
878 
879   if (WroteVol) {
880     Jmsg0(jcr, M_ERROR, 0, _("Hey!!!!! WroteVol non-zero !!!!!\n"));
881     Pmsg0(190, "Hey!!!!! WroteVol non-zero !!!!!\n");
882   }
883   /*
884    * First erase all memory of the current volume
885    */
886   FreeVolume(dev);
887   dev->block_num = dev->file = 0;
888   dev->EndBlock = dev->EndFile = 0;
889   VolumeCatalogInfo empty_VolumeCatalogInfo;
890   dev->VolCatInfo = empty_VolumeCatalogInfo;
891   dev->ClearVolhdr();
892 
893   /*
894    * Force re-read of label
895    */
896   dev->ClearLabeled();
897   dev->ClearRead();
898   dev->ClearAppend();
899   dev->label_type = B_BAREOS_LABEL;
900   VolumeName[0] = 0;
901 
902   if (dev->IsOpen() && (!dev->IsTape() || !dev->HasCap(CAP_ALWAYSOPEN))) {
903     dev->close(dcr);
904   }
905 
906   /*
907    * If we have not closed the device, then at least rewind the tape
908    */
909   if (dev->IsOpen()) { dev->OfflineOrRewind(); }
910   Dmsg0(190, "ReleaseVolume\n");
911 }
912 
913 /**
914  *      Insanity check
915  *
916  * Check to see if the tape position as defined by the OS is
917  *  the same as our concept.  If it is not,
918  *  it means the user has probably manually rewound the tape.
919  * Note, we check only if num_writers == 0, but this code will
920  *  also work fine for any number of writers. If num_writers > 0,
921  *  we probably should cancel all jobs using this device, or
922  *  perhaps even abort the SD, or at a minimum, mark the tape
923  *  in error.  Another strategy with num_writers == 0, would be
924  *  to rewind the tape and do a new eod() request.
925  */
IsTapePositionOk()926 bool DeviceControlRecord::IsTapePositionOk()
927 {
928   if (dev->IsTape() && dev->num_writers == 0) {
929     int32_t file = dev->GetOsTapeFile();
930     if (file >= 0 && file != (int32_t)dev->GetFile()) {
931       Jmsg(jcr, M_ERROR, 0,
932            _("Invalid tape position on volume \"%s\""
933              " on device %s. Expected %d, got %d\n"),
934            dev->VolHdr.VolumeName, dev->print_name(), dev->GetFile(), file);
935       /*
936        * If the current file is greater than zero, it means we probably
937        *  have some bad count of EOF marks, so mark tape in error.  Otherwise
938        *  the operator might have moved the tape, so we just release it
939        *  and try again.
940        */
941       if (file > 0) { MarkVolumeInError(); }
942       ReleaseVolume();
943       return false;
944     }
945   }
946   return true;
947 }
948 
949 /**
950  * If we are reading, we come here at the end of the tape
951  *  and see if there are more volumes to be mounted.
952  */
MountNextReadVolume(DeviceControlRecord * dcr)953 bool MountNextReadVolume(DeviceControlRecord* dcr)
954 {
955   Device* dev = dcr->dev;
956   JobControlRecord* jcr = dcr->jcr;
957   Dmsg2(90, "NumReadVolumes=%d CurReadVolume=%d\n", jcr->impl->NumReadVolumes,
958         jcr->impl->CurReadVolume);
959 
960   VolumeUnused(dcr); /* release current volume */
961   /*
962    * End Of Tape -- mount next Volume (if another specified)
963    */
964   if (jcr->impl->NumReadVolumes > 1
965       && jcr->impl->CurReadVolume < jcr->impl->NumReadVolumes) {
966     dev->Lock();
967     dev->close(dcr);
968     dev->SetRead();
969     dcr->SetReserved();
970     dev->Unlock();
971     if (!AcquireDeviceForRead(dcr)) {
972       Jmsg2(jcr, M_FATAL, 0, _("Cannot open Dev=%s, Vol=%s\n"),
973             dev->print_name(), dcr->VolumeName);
974       return false;
975     }
976     return true; /* next volume mounted */
977   }
978   Dmsg0(90, "End of Device reached.\n");
979   return false;
980 }
981 
982 } /* namespace storagedaemon */
983