]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/device.c
More tweaks to the mount volume routines to get everything
[bacula/bacula] / bacula / src / stored / device.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2000-2007 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 John Walker.
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  *  Higher Level Device routines.
31  *  Knows about Bacula tape labels and such
32  *
33  *  NOTE! In general, subroutines that have the word
34  *        "device" in the name do locking.  Subroutines
35  *        that have the word "dev" in the name do not
36  *        do locking.  Thus if xxx_device() calls
37  *        yyy_dev(), all is OK, but if xxx_device()
38  *        calls yyy_device(), everything will hang.
39  *        Obviously, no zzz_dev() is allowed to call
40  *        a www_device() or everything falls apart.
41  *
42  * Concerning the routines dev->r_lock()() and block_device()
43  *  see the end of this module for details.  In general,
44  *  blocking a device leaves it in a state where all threads
45  *  other than the current thread block when they attempt to
46  *  lock the device. They remain suspended (blocked) until the device
47  *  is unblocked. So, a device is blocked during an operation
48  *  that takes a long time (initialization, mounting a new
49  *  volume, ...) locking a device is done for an operation
50  *  that takes a short time such as writing data to the
51  *  device.
52  *
53  *
54  *   Kern Sibbald, MM, MMI
55  *
56  *   Version $Id$
57  */
58
59 #include "bacula.h"                   /* pull in global headers */
60 #include "stored.h"                   /* pull in Storage Deamon headers */
61
62 /* Forward referenced functions */
63
64 /*
65  * This is the dreaded moment. We either have an end of
66  * medium condition or worse, and error condition.
67  * Attempt to "recover" by obtaining a new Volume.
68  *
69  * Here are a few things to know:
70  *  dcr->VolCatInfo contains the info on the "current" tape for this job.
71  *  dev->VolCatInfo contains the info on the tape in the drive.
72  *    The tape in the drive could have changed several times since
73  *    the last time the job used it (jcr->VolCatInfo).
74  *  dcr->VolumeName is the name of the current/desired tape in the drive.
75  *
76  * We enter with device locked, and
77  *     exit with device locked.
78  *
79  * Note, we are called only from one place in block.c for the daemons.  
80  *     The btape utility calls it from btape.c.
81  *
82  *  Returns: true  on success
83  *           false on failure
84  */
85 bool fixup_device_block_write_error(DCR *dcr)
86 {
87    char PrevVolName[MAX_NAME_LENGTH];
88    DEV_BLOCK *label_blk;
89    DEV_BLOCK *block = dcr->block;
90    char b1[30], b2[30];
91    time_t wait_time;
92    char dt[MAX_TIME_LENGTH];
93    JCR *jcr = dcr->jcr;
94    DEVICE *dev = dcr->dev;
95    int blocked = dev->blocked();         /* save any previous blocked status */
96    bool ok = false;
97
98    wait_time = time(NULL);
99
100    Dmsg0(100, "Enter fixup_device_block_write_error\n");
101
102    /*
103     * If we are blocked at entry, unblock it, and set our own block status
104     */
105    if (blocked != BST_NOT_BLOCKED) {
106       unblock_device(dev);
107    }
108    block_device(dev, BST_DOING_ACQUIRE);
109
110    /* Continue unlocked, but leave BLOCKED */
111    dev->dunlock();
112
113    bstrncpy(PrevVolName, dev->VolCatInfo.VolCatName, sizeof(PrevVolName));
114    bstrncpy(dev->VolHdr.PrevVolumeName, PrevVolName, sizeof(dev->VolHdr.PrevVolumeName));
115
116    label_blk = new_block(dev);
117    dcr->block = label_blk;
118
119    /* Inform User about end of medium */
120    Jmsg(jcr, M_INFO, 0, _("End of medium on Volume \"%s\" Bytes=%s Blocks=%s at %s.\n"),
121         PrevVolName, edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, b1),
122         edit_uint64_with_commas(dev->VolCatInfo.VolCatBlocks, b2),
123         bstrftime(dt, sizeof(dt), time(NULL)));
124
125    /* Called with have_vol=false, release=true */
126    if (!mount_next_write_volume(dcr, false, true)) {
127       free_block(label_blk);
128       dcr->block = block;
129       dev->dlock();  
130       goto bail_out;
131    }
132    dev->dlock();                    /* lock again */
133
134    dev->VolCatInfo.VolCatJobs++;              /* increment number of jobs on vol */
135    dir_update_volume_info(dcr, false);        /* send Volume info to Director */
136
137    Jmsg(jcr, M_INFO, 0, _("New volume \"%s\" mounted on device %s at %s.\n"),
138       dcr->VolumeName, dev->print_name(), bstrftime(dt, sizeof(dt), time(NULL)));
139
140    /*
141     * If this is a new tape, the label_blk will contain the
142     *  label, so write it now. If this is a previously
143     *  used tape, mount_next_write_volume() will return an
144     *  empty label_blk, and nothing will be written.
145     */
146    Dmsg0(190, "write label block to dev\n");
147    if (!write_block_to_dev(dcr)) {
148       berrno be;
149       Pmsg1(0, _("write_block_to_device Volume label failed. ERR=%s"),
150         be.bstrerror(dev->dev_errno));
151       free_block(label_blk);
152       dcr->block = block;
153       goto bail_out;
154    }
155    free_block(label_blk);
156    dcr->block = block;
157
158    /*
159     * Walk through all attached jcrs indicating the volume has changed
160     */
161    Dmsg1(100, "Walk attached dcrs. Volume=%s\n", dev->VolCatInfo.VolCatName);
162    DCR *mdcr;
163    foreach_dlist(mdcr, dev->attached_dcrs) {
164       JCR *mjcr = mdcr->jcr;
165       if (mjcr->JobId == 0) {
166          continue;                 /* ignore console */
167       }
168       mdcr->NewVol = true;
169       if (jcr != mjcr) {
170          bstrncpy(mdcr->VolumeName, dcr->VolumeName, sizeof(mdcr->VolumeName));
171       }
172    }
173
174    /* Clear NewVol now because dir_get_volume_info() already done */
175    jcr->dcr->NewVol = false;
176    set_new_volume_parameters(dcr);
177
178    jcr->run_time += time(NULL) - wait_time; /* correct run time for mount wait */
179
180    /* Write overflow block to device */
181    Dmsg0(190, "Write overflow block to dev\n");
182    if (!write_block_to_dev(dcr)) {
183       berrno be;
184       Pmsg1(0, _("write_block_to_device overflow block failed. ERR=%s"),
185         be.bstrerror(dev->dev_errno));
186       goto bail_out;
187    }
188    ok = true;
189
190 bail_out:
191    /*
192     * At this point, the device is locked and blocked.
193     * Unblock the device, restore any entry blocked condition, then
194     *   return leaving the device locked (as it was on entry).
195     */
196    unblock_device(dev);
197    if (blocked != BST_NOT_BLOCKED) {
198       block_device(dev, blocked);
199    }
200    return ok;                               /* device locked */
201 }
202
203 /*
204  * We have a new Volume mounted, so reset the Volume parameters
205  *  concerning this job.  The global changes were made earlier
206  *  in the dev structure.
207  */
208 void set_new_volume_parameters(DCR *dcr)
209 {
210    JCR *jcr = dcr->jcr;
211    DEVICE *dev = dcr->dev;
212    if (dcr->NewVol && !dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE)) {
213       Jmsg1(jcr, M_ERROR, 0, "%s", jcr->errmsg);
214    }
215    /* Set new start/end positions */
216    if (dev->is_tape()) {
217       dcr->StartBlock = dev->block_num;
218       dcr->StartFile = dev->file;
219    } else {
220       dcr->StartBlock = (uint32_t)dev->file_addr;
221       dcr->StartFile  = (uint32_t)(dev->file_addr >> 32);
222    }
223    /* Reset indicies */
224    dcr->VolFirstIndex = 0;
225    dcr->VolLastIndex = 0;
226    jcr->NumWriteVolumes++;
227    dcr->NewVol = false;
228    dcr->WroteVol = false;
229 }
230
231 /*
232  * We are now in a new Volume file, so reset the Volume parameters
233  *  concerning this job.  The global changes were made earlier
234  *  in the dev structure.
235  */
236 void set_new_file_parameters(DCR *dcr)
237 {
238    DEVICE *dev = dcr->dev;
239
240    /* Set new start/end positions */
241    if (dev->is_tape()) {
242       dcr->StartBlock = dev->block_num;
243       dcr->StartFile = dev->file;
244    } else {
245       dcr->StartBlock = (uint32_t)dev->file_addr;
246       dcr->StartFile  = (uint32_t)(dev->file_addr >> 32);
247    }
248    /* Reset indicies */
249    dcr->VolFirstIndex = 0;
250    dcr->VolLastIndex = 0;
251    dcr->NewFile = false;
252    dcr->WroteVol = false;
253 }
254
255
256
257 /*
258  *   First Open of the device. Expect dev to already be initialized.
259  *
260  *   This routine is used only when the Storage daemon starts
261  *   and always_open is set, and in the stand-alone utility
262  *   routines such as bextract.
263  *
264  *   Note, opening of a normal file is deferred to later so
265  *    that we can get the filename; the device_name for
266  *    a file is the directory only.
267  *
268  *   Returns: false on failure
269  *            true  on success
270  */
271 bool first_open_device(DCR *dcr)
272 {
273    DEVICE *dev = dcr->dev;
274    bool ok = true;
275
276    Dmsg0(120, "start open_output_device()\n");
277    if (!dev) {
278       return false;
279    }
280
281    dev->r_dlock();
282
283    /* Defer opening files */
284    if (!dev->is_tape()) {
285       Dmsg0(129, "Device is file, deferring open.\n");
286       goto bail_out;
287    }
288
289     int mode;
290     if (dev->has_cap(CAP_STREAM)) {
291        mode = OPEN_WRITE_ONLY;
292     } else {
293        mode = OPEN_READ_ONLY;
294     }
295    Dmsg0(129, "Opening device.\n");
296    if (dev->open(dcr, mode) < 0) {
297       Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg);
298       ok = false;
299       goto bail_out;
300    }
301    Dmsg1(129, "open dev %s OK\n", dev->print_name());
302
303 bail_out:
304    dev->dunlock();
305    return ok;
306 }
307
308 /*
309  * Make sure device is open, if not do so
310  */
311 bool open_device(DCR *dcr)
312 {
313    DEVICE *dev = dcr->dev;
314    /* Open device */
315    int mode;
316    if (dev->has_cap(CAP_STREAM)) {
317       mode = OPEN_WRITE_ONLY;
318    } else {
319       mode = OPEN_READ_WRITE;
320    }
321    if (dev->open(dcr, mode) < 0) {
322       /* If polling, ignore the error */
323       /* If DVD, also ignore the error, very often you cannot open the device
324        * (when there is no DVD, or when the one inserted is a wrong one) */
325       if (!dev->poll && !dev->is_dvd() && !dev->is_removable()) {
326          Jmsg2(dcr->jcr, M_FATAL, 0, _("Unable to open device %s: ERR=%s\n"),
327             dev->print_name(), dev->bstrerror());
328          Pmsg2(000, _("Unable to open archive %s: ERR=%s\n"), 
329             dev->print_name(), dev->bstrerror());
330       }
331       return false;
332    }
333    return true;
334 }