]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/mount.c
- Implement first cut of Migration.
[bacula/bacula] / bacula / src / stored / mount.c
1 /*
2  *
3  *  Routines for handling mounting tapes for reading and for
4  *    writing.
5  *
6  *   Kern Sibbald, August MMII
7  *
8  *   Version $Id$
9  */
10 /*
11    Copyright (C) 2002-2006 Kern Sibbald
12
13    This program is free software; you can redistribute it and/or
14    modify it under the terms of the GNU General Public License
15    version 2 as amended with additional clauses defined in the
16    file LICENSE in the main source directory.
17
18    This program is distributed in the hope that it will be useful,
19    but WITHOUT ANY WARRANTY; without even the implied warranty of
20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
21    the file LICENSE for additional details.
22
23  */
24
25 #include "bacula.h"                   /* pull in global headers */
26 #include "stored.h"                   /* pull in Storage Deamon headers */
27
28 static void mark_volume_not_inchanger(DCR *dcr);
29 static int try_autolabel(DCR *dcr);
30
31 enum {
32    try_next_vol = 1,
33    try_read_vol,
34    try_error,
35    try_default
36 };
37
38 /*
39  * If release is set, we rewind the current volume,
40  * which we no longer want, and ask the user (console)
41  * to mount the next volume.
42  *
43  *  Continue trying until we get it, and then ensure
44  *  that we can write on it.
45  *
46  * This routine returns a 0 only if it is REALLY
47  *  impossible to get the requested Volume.
48  *
49  */
50 bool mount_next_write_volume(DCR *dcr, bool release)
51 {
52    int retry = 0;
53    bool ask = false, recycle, autochanger;
54    int vol_label_status;
55    DEVICE *dev = dcr->dev;
56    JCR *jcr = dcr->jcr;
57    DEV_BLOCK *block = dcr->block;
58    int mode;
59
60    Dmsg1(150, "Enter mount_next_volume(release=%d)\n", release);
61
62    init_device_wait_timers(dcr);
63
64    /*
65     * Attempt to mount the next volume. If something non-fatal goes
66     *  wrong, we come back here to re-try (new op messages, re-read
67     *  Volume, ...)
68     */
69 mount_next_vol:
70    Dmsg1(150, "mount_next_vol retry=%d\n", retry);
71    /* Ignore retry if this is poll request */
72    if (!dev->poll && retry++ > 4) {
73       /* Last ditch effort before giving up, force operator to respond */
74       dcr->VolCatInfo.Slot = 0;
75       if (!dir_ask_sysop_to_mount_volume(dcr)) {
76          Jmsg(jcr, M_FATAL, 0, _("Too many errors trying to mount device %s.\n"),
77               dev->print_name());
78          return false;
79       }
80    }
81    if (job_canceled(jcr)) {
82       Jmsg(jcr, M_FATAL, 0, _("Job %d canceled.\n"), jcr->JobId);
83       return false;
84    }
85    recycle = false;
86    if (release) {
87       Dmsg0(150, "mount_next_volume release=1\n");
88       release_volume(dcr);
89       ask = true;                     /* ask operator to mount tape */
90    }
91
92    /*
93     * Get Director's idea of what tape we should have mounted.
94     *    in dcr->VolCatInfo
95     */
96    Dmsg0(200, "Before dir_find_next_appendable_volume.\n");
97    while (!dir_find_next_appendable_volume(dcr)) {
98        Dmsg0(200, "not dir_find_next\n");
99        if (!dir_ask_sysop_to_create_appendable_volume(dcr)) {
100          return false;
101        }
102        Dmsg0(200, "Again dir_find_next_append...\n");
103    }
104    if (job_canceled(jcr)) {
105       return false;
106    }
107    Dmsg3(150, "After find_next_append. Vol=%s Slot=%d Parts=%d\n",
108          dcr->VolCatInfo.VolCatName, dcr->VolCatInfo.Slot, dcr->VolCatInfo.VolCatParts);
109    
110    /*
111     * Get next volume and ready it for append
112     * This code ensures that the device is ready for
113     * writing. We start from the assumption that there
114     * may not be a tape mounted.
115     *
116     * If the device is a file, we create the output
117     * file. If it is a tape, we check the volume name
118     * and move the tape to the end of data.
119     *
120     */
121    if (autoload_device(dcr, 1, NULL) > 0) {
122       autochanger = true;
123       ask = false;
124    } else {
125       autochanger = false;
126       dcr->VolCatInfo.Slot = 0;
127    }
128    Dmsg1(200, "autoload_dev returns %d\n", autochanger);
129    /*
130     * If we autochanged to correct Volume or (we have not just
131     *   released the Volume AND we can automount) we go ahead
132     *   and read the label. If there is no tape in the drive,
133     *   we will err, recurse and ask the operator the next time.
134     */
135    if (!release && dev->is_tape() && dev->has_cap(CAP_AUTOMOUNT)) {
136       Dmsg0(150, "(1)Ask=0\n");
137       ask = false;                 /* don't ask SYSOP this time */
138    }
139    /* Don't ask if not removable */
140    if (!dev->is_removable()) {
141       Dmsg0(150, "(2)Ask=0\n");
142       ask = false;
143    }
144    Dmsg2(150, "Ask=%d autochanger=%d\n", ask, autochanger);
145    release = true;                /* release next time if we "recurse" */
146
147    if (ask && !dir_ask_sysop_to_mount_volume(dcr)) {
148       Dmsg0(150, "Error return ask_sysop ...\n");
149       return false;          /* error return */
150    }
151    if (job_canceled(jcr)) {
152       return false;
153    }
154    Dmsg1(150, "want vol=%s\n", dcr->VolumeName);
155
156    if (dev->poll && dev->has_cap(CAP_CLOSEONPOLL)) {
157       dev->close();
158    }
159
160    /* Ensure the device is open */
161    if (dev_cap(dev, CAP_STREAM)) {
162       mode = OPEN_WRITE_ONLY;
163    } else {
164       mode = OPEN_READ_WRITE;
165    }
166    while (dev->open(dcr, mode) < 0) {
167       Dmsg0(000, "open_device failed\n");
168       if (dev->is_file() && dev->is_removable()) {
169          Dmsg0(000, "call scan_dir_for_vol\n");
170          if (dev->scan_dir_for_volume(dcr)) {
171             break;                    /* got a valid volume */
172          }
173       }
174       if (try_autolabel(dcr) == try_read_vol) {
175          break;                       /* created a new volume label */
176       }
177       /* If DVD, ignore the error, very often you cannot open the device
178        * (when there is no DVD, or when the one inserted is a wrong one) */
179       if (dev->poll || dev->is_dvd() || dev->is_removable()) {
180          goto mount_next_vol;
181       } else {
182          return false;
183       }
184    }
185
186    /*
187     * Now make sure we have the right tape mounted
188     */
189 read_volume:
190    /*
191     * If we are writing to a stream device, ASSUME the volume label
192     *  is correct.
193     */
194    if (dev->has_cap(CAP_STREAM)) {
195       vol_label_status = VOL_OK;
196       create_volume_label(dev, dcr->VolumeName, "Default");
197       dev->VolHdr.LabelType = PRE_LABEL;
198    } else {
199       vol_label_status = read_dev_volume_label(dcr);
200    }
201    if (job_canceled(jcr)) {
202       return false;
203    }
204
205    Dmsg2(150, "Want dirVol=%s dirStat=%s\n", dcr->VolumeName,
206       dcr->VolCatInfo.VolCatStatus);
207    /*
208     * At this point, dev->VolCatInfo has what is in the drive, if anything,
209     *          and   dcr->VolCatInfo has what the Director wants.
210     */
211    switch (vol_label_status) {
212    case VOL_OK:
213       Dmsg1(150, "Vol OK name=%s\n", dcr->VolumeName);
214       memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
215       recycle = strcmp(dev->VolCatInfo.VolCatStatus, "Recycle") == 0;
216       break;                    /* got a Volume */
217    case VOL_NAME_ERROR:
218       VOLUME_CAT_INFO VolCatInfo, devVolCatInfo;
219
220       /* If not removable, Volume is broken */
221       if (!dev->is_removable()) {
222          Jmsg(jcr, M_WARNING, 0, _("Volume \"%s\" not on device %s.\n"),
223             dcr->VolumeName, dev->print_name());
224          mark_volume_in_error(dcr);
225          goto mount_next_vol;
226       }
227
228       Dmsg1(150, "Vol NAME Error Name=%s\n", dcr->VolumeName);
229       /* If polling and got a previous bad name, ignore it */
230       if (dev->poll && strcmp(dev->BadVolName, dev->VolHdr.VolumeName) == 0) {
231          ask = true;
232          Dmsg1(200, "Vol Name error supress due to poll. Name=%s\n", dcr->VolumeName);
233          goto mount_next_vol;
234       }
235       /*
236        * OK, we got a different volume mounted. First save the
237        *  requested Volume info (dcr) structure, then query if
238        *  this volume is really OK. If not, put back the desired
239        *  volume name, mark it not in changer and continue.
240        */
241       memcpy(&VolCatInfo, &dcr->VolCatInfo, sizeof(VolCatInfo));
242       memcpy(&devVolCatInfo, &dev->VolCatInfo, sizeof(devVolCatInfo));
243       /* Check if this is a valid Volume in the pool */
244       bstrncpy(dcr->VolumeName, dev->VolHdr.VolumeName, sizeof(dcr->VolumeName));
245       if (!dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE)) {
246          /* Restore desired volume name, note device info out of sync */
247          /* This gets the info regardless of the Pool */
248          bstrncpy(dcr->VolumeName, dev->VolHdr.VolumeName, sizeof(dcr->VolumeName));
249          if (autochanger && !dir_get_volume_info(dcr, GET_VOL_INFO_FOR_READ)) {
250             mark_volume_not_inchanger(dcr);
251          }
252          memcpy(&dev->VolCatInfo, &devVolCatInfo, sizeof(dev->VolCatInfo));
253          bstrncpy(dev->BadVolName, dev->VolHdr.VolumeName, sizeof(dev->BadVolName));
254          Jmsg(jcr, M_WARNING, 0, _("Director wanted Volume \"%s\".\n"
255               "    Current Volume \"%s\" not acceptable because:\n"
256               "    %s"),
257              VolCatInfo.VolCatName, dev->VolHdr.VolumeName,
258              jcr->dir_bsock->msg);
259          ask = true;
260          goto mount_next_vol;
261       }
262       /* This was not the volume we expected, but it is OK with
263        * the Director, so use it.
264        */
265       Dmsg1(150, "want new name=%s\n", dcr->VolumeName);
266       memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
267       recycle = strcmp(dev->VolCatInfo.VolCatStatus, "Recycle") == 0;
268       break;                /* got a Volume */
269    /*
270     * At this point, we assume we have a blank tape mounted.
271     */
272    case VOL_IO_ERROR:
273       if (dev->is_dvd()) {
274          Jmsg(jcr, M_FATAL, 0, "%s", jcr->errmsg);
275          mark_volume_in_error(dcr);
276          return false;       /* we could not write on DVD */
277       }
278       /* Fall through wanted */
279    case VOL_NO_LABEL:
280       switch (try_autolabel(dcr)) {
281       case try_next_vol:
282          goto mount_next_vol;
283       case try_read_vol:
284          goto read_volume;
285       case try_error:
286          return false;
287       case try_default:
288          break;
289       }
290
291       /* NOTE! Fall-through wanted. */
292    case VOL_NO_MEDIA:
293    default:
294       Dmsg0(200, "VOL_NO_MEDIA or default.\n");
295       /* Send error message */
296       if (!dev->poll) {
297       } else {
298          Dmsg1(200, "Msg suppressed by poll: %s\n", jcr->errmsg);
299       }
300       ask = true;
301       /* Needed, so the medium can be changed */
302       if (dev->requires_mount()) {
303          dev->close();
304       }
305       goto mount_next_vol;
306    }
307
308    /*
309     * See if we have a fresh tape or a tape with data.
310     *
311     * Note, if the LabelType is PRE_LABEL, it was labeled
312     *  but never written. If so, rewrite the label but set as
313     *  VOL_LABEL.  We rewind and return the label (reconstructed)
314     *  in the block so that in the case of a new tape, data can
315     *  be appended just after the block label.  If we are writing
316     *  a second volume, the calling routine will write the label
317     *  before writing the overflow block.
318     *
319     *  If the tape is marked as Recycle, we rewrite the label.
320     */
321    if (dev->VolHdr.LabelType == PRE_LABEL || recycle) {
322       if (!rewrite_volume_label(dcr, recycle)) {
323          mark_volume_in_error(dcr);
324          goto mount_next_vol;
325       }
326    } else {
327       /*
328        * OK, at this point, we have a valid Bacula label, but
329        * we need to position to the end of the volume, since we are
330        * just now putting it into append mode.
331        */
332       Dmsg0(200, "Device previously written, moving to end of data\n");
333       Jmsg(jcr, M_INFO, 0, _("Volume \"%s\" previously written, moving to end of data.\n"),
334          dcr->VolumeName);
335       if (!dev->eod()) {
336          Jmsg(jcr, M_ERROR, 0, _("Unable to position to end of data on device %s: ERR=%s\n"),
337             dev->print_name(), strerror_dev(dev));
338          mark_volume_in_error(dcr);
339          goto mount_next_vol;
340       }
341       /* *****FIXME**** we should do some checking for files too */
342       if (dev->is_tape()) {
343          /*
344           * Check if we are positioned on the tape at the same place
345           * that the database says we should be.
346           */
347          if (dev->VolCatInfo.VolCatFiles == dev_file(dev)) {
348             Jmsg(jcr, M_INFO, 0, _("Ready to append to end of Volume \"%s\" at file=%d.\n"),
349                  dcr->VolumeName, dev_file(dev));
350          } else {
351             Jmsg(jcr, M_ERROR, 0, _("I cannot write on Volume \"%s\" because:\n"
352 "The number of files mismatch! Volume=%u Catalog=%u\n"),
353                  dcr->VolumeName, dev_file(dev), dev->VolCatInfo.VolCatFiles);
354             mark_volume_in_error(dcr);
355             goto mount_next_vol;
356          }
357       }
358       dev->VolCatInfo.VolCatMounts++;      /* Update mounts */
359       Dmsg1(150, "update volinfo mounts=%d\n", dev->VolCatInfo.VolCatMounts);
360       if (!dir_update_volume_info(dcr, false)) {
361          return false;
362       }
363       
364       /*
365        * DVD : check if the last part was removed or truncated, or if a written
366        * part was overwritten.   
367        * We need to do it after dir_update_volume_info, so we have the EndBlock
368        * info. (nb: I don't understand why VolCatFiles is set (used to check
369        * tape file number), but not EndBlock)
370        * Maybe could it be changed "dev->is_file()" (would remove the fixme above)   
371        *
372        * Disabled: I had problems with this code... 
373        * (maybe is it related to the seek bug ?)   
374        */
375 #ifdef xxx
376       if (dev->is_dvd()) {
377          Dmsg2(150, "DVD/File sanity check addr=%u vs endblock=%u\n", (unsigned int)dev->file_addr, (unsigned int)dev->VolCatInfo.EndBlock);
378          if (dev->file_addr == dev->VolCatInfo.EndBlock+1) {
379             Jmsg(jcr, M_INFO, 0, _("Ready to append to end of Volume \"%s\" at file address=%u.\n"),
380                  dcr->VolumeName, (unsigned int)dev->file_addr);
381          }
382          else {
383             Jmsg(jcr, M_ERROR, 0, _("I cannot write on Volume \"%s\" because:\n"
384                                     "The EOD file address is wrong: Volume file address=%u != Catalog Endblock=%u(+1)\n"
385                                     "You probably removed DVD last part in spool directory.\n"),
386                  dcr->VolumeName, (unsigned int)dev->file_addr, (unsigned int)dev->VolCatInfo.EndBlock);
387             mark_volume_in_error(dcr);
388             goto mount_next_vol;
389          }
390       }
391 #endif
392       
393       /* Return an empty block */
394       empty_block(block);             /* we used it for reading so set for write */
395    }
396    dev->set_append();
397    Dmsg0(150, "set APPEND, normal return from read_dev_for_append\n");
398    return true;
399 }
400
401 /*
402  * If permitted, we label the device, make sure we can do
403  *   it by checking that the VolCatBytes is zero => not labeled,
404  *   once the Volume is labeled we don't want to label another
405  *   blank tape with the same name.  For disk, we go ahead and
406  *   label it anyway, because the OS insures that there is only
407  *   one Volume with that name.
408  * As noted above, at this point dcr->VolCatInfo has what
409  *   the Director wants and dev->VolCatInfo has info on the
410  *   previous tape (or nothing).
411  */
412 static int try_autolabel(DCR *dcr)
413 {
414    DEVICE *dev = dcr->dev;
415    if (dev->has_cap(CAP_LABEL) && (dcr->VolCatInfo.VolCatBytes == 0 ||
416          (!dev->is_tape() && strcmp(dcr->VolCatInfo.VolCatStatus,
417                                 "Recycle") == 0))) {
418       Dmsg0(150, "Create volume label\n");
419       /* Create a new Volume label and write it to the device */
420       if (!write_new_volume_label_to_dev(dcr, dcr->VolumeName,
421              dcr->pool_name)) {
422          Dmsg0(150, "!write_vol_label\n");
423          mark_volume_in_error(dcr);
424          return try_next_vol;
425       }
426       Dmsg0(150, "dir_update_vol_info. Set Append\n");
427       /* Copy Director's info into the device info */
428       memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
429       if (!dir_update_volume_info(dcr, true)) {  /* indicate tape labeled */
430          return try_error;
431       }
432       Jmsg(dcr->jcr, M_INFO, 0, _("Labeled new Volume \"%s\" on device %s.\n"),
433          dcr->VolumeName, dev->print_name());
434       return try_read_vol;   /* read label we just wrote */
435    }
436    if (!dev->has_cap(CAP_LABEL) && dcr->VolCatInfo.VolCatBytes == 0) {
437       Jmsg(dcr->jcr, M_INFO, 0, _("Warning device %s not configured to autolabel Volumes.\n"), 
438          dev->print_name());
439    }
440    /* If not removable, Volume is broken */
441    if (!dev->is_removable()) {
442       Jmsg(dcr->jcr, M_WARNING, 0, _("Volume \"%s\" not on device %s.\n"),
443          dcr->VolumeName, dev->print_name());
444       mark_volume_in_error(dcr);
445       return try_next_vol;
446    }
447    return try_default;
448 }
449
450
451 /*
452  * Mark volume in error in catalog
453  */
454 void mark_volume_in_error(DCR *dcr)
455 {
456    DEVICE *dev = dcr->dev;
457    Jmsg(dcr->jcr, M_INFO, 0, _("Marking Volume \"%s\" in Error in Catalog.\n"),
458         dcr->VolumeName);
459    memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
460    bstrncpy(dev->VolCatInfo.VolCatStatus, "Error", sizeof(dev->VolCatInfo.VolCatStatus));
461    Dmsg0(150, "dir_update_vol_info. Set Error.\n");
462    dir_update_volume_info(dcr, false);
463 }
464
465 /*
466  * The Volume is not in the correct slot, so mark this
467  *   Volume as not being in the Changer.
468  */
469 static void mark_volume_not_inchanger(DCR *dcr)
470 {
471    JCR *jcr = dcr->jcr;
472    DEVICE *dev = dcr->dev;
473    Jmsg(jcr, M_ERROR, 0, _("Autochanger Volume \"%s\" not found in slot %d.\n"
474 "    Setting InChanger to zero in catalog.\n"),
475         dcr->VolCatInfo.VolCatName, dcr->VolCatInfo.Slot);
476    memcpy(&dev->VolCatInfo, &dcr->VolCatInfo, sizeof(dev->VolCatInfo));
477    dcr->VolCatInfo.InChanger = false;
478    dev->VolCatInfo.InChanger = false;
479    Dmsg0(400, "update vol info in mount\n");
480    dir_update_volume_info(dcr, true);  /* set new status */
481 }
482
483 /*
484  * Either because we are going to hang a new volume, or because
485  *  of explicit user request, we release the current volume.
486  */
487 void release_volume(DCR *dcr)
488 {
489    JCR *jcr = dcr->jcr;
490    DEVICE *dev = dcr->dev;
491    if (dcr->WroteVol) {
492       Jmsg0(jcr, M_ERROR, 0, _("Hey!!!!! WroteVol non-zero !!!!!\n"));
493       Dmsg0(190, "Hey!!!!! WroteVol non-zero !!!!!\n");
494    }
495    /*
496     * First erase all memory of the current volume
497     */
498    dev->block_num = dev->file = 0;
499    dev->EndBlock = dev->EndFile = 0;
500    memset(&dev->VolCatInfo, 0, sizeof(dev->VolCatInfo));
501    memset(&dcr->VolCatInfo, 0, sizeof(dcr->VolCatInfo));
502    free_volume(dev);
503    memset(&dev->VolHdr, 0, sizeof(dev->VolHdr));
504    /* Force re-read of label */
505    dev->clear_labeled();
506    dev->clear_read();
507    dev->clear_append();
508    dev->label_type = B_BACULA_LABEL;
509    dcr->VolumeName[0] = 0;
510
511    if (dev->is_open() && (!dev->is_tape() || !dev_cap(dev, CAP_ALWAYSOPEN))) {
512       dev->close();
513    }
514
515    /* If we have not closed the device, then at least rewind the tape */
516    if (dev->is_open()) {
517       dev->offline_or_rewind();
518    }
519    Dmsg0(190, "release_volume\n");
520 }
521
522 /*
523  * If we are reading, we come here at the end of the tape
524  *  and see if there are more volumes to be mounted.
525  */
526 bool mount_next_read_volume(DCR *dcr)
527 {
528    DEVICE *dev = dcr->dev;
529    JCR *jcr = dcr->jcr;
530    Dmsg2(90, "NumVolumes=%d CurVolume=%d\n", jcr->NumVolumes, jcr->CurVolume);
531    /*
532     * End Of Tape -- mount next Volume (if another specified)
533     */
534    if (jcr->NumVolumes > 1 && jcr->CurVolume < jcr->NumVolumes) {
535       dev->close();
536       if (!acquire_device_for_read(dcr)) {
537          Jmsg2(jcr, M_FATAL, 0, _("Cannot open Dev=%s, Vol=%s\n"), dev->print_name(),
538                dcr->VolumeName);
539          return false;
540       }
541       return true;                    /* next volume mounted */
542    }
543    Dmsg0(90, "End of Device reached.\n");
544    return false;
545 }