]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/device.c
Make out of freespace non-fatal for removable devices -- i.e. behaves like tape
[bacula/bacula] / bacula / src / stored / device.c
1 /*
2    Bacula(R) - The Network Backup Solution
3
4    Copyright (C) 2000-2017 Kern Sibbald
5
6    The original author of Bacula is Kern Sibbald, with contributions
7    from many others, a complete list can be found in the file AUTHORS.
8
9    You may use this file and others of this release according to the
10    license defined in the LICENSE file, which includes the Affero General
11    Public License, v3.0 ("AGPLv3") and some additional permissions and
12    terms pursuant to its AGPLv3 Section 7.
13
14    This notice must be preserved when any source code is
15    conveyed and/or propagated.
16
17    Bacula(R) is a registered trademark of Kern Sibbald.
18 */
19 /*
20  *
21  *  Higher Level Device routines.
22  *  Knows about Bacula tape labels and such
23  *
24  *  NOTE! In general, subroutines that have the word
25  *        "device" in the name do locking.  Subroutines
26  *        that have the word "dev" in the name do not
27  *        do locking.  Thus if xxx_device() calls
28  *        yyy_dev(), all is OK, but if xxx_device()
29  *        calls yyy_device(), everything will hang.
30  *        Obviously, no zzz_dev() is allowed to call
31  *        a www_device() or everything falls apart.
32  *
33  * Concerning the routines dev->rLock()() and block_device()
34  *  see the end of this module for details.  In general,
35  *  blocking a device leaves it in a state where all threads
36  *  other than the current thread block when they attempt to
37  *  lock the device. They remain suspended (blocked) until the device
38  *  is unblocked. So, a device is blocked during an operation
39  *  that takes a long time (initialization, mounting a new
40  *  volume, ...) locking a device is done for an operation
41  *  that takes a short time such as writing data to the
42  *  device.
43  *
44  *
45  *   Kern Sibbald, MM, MMI
46  *
47  */
48
49 #include "bacula.h"                   /* pull in global headers */
50 #include "stored.h"                   /* pull in Storage Deamon headers */
51
52 /* Forward referenced functions */
53
54 /*
55  * This is the dreaded moment. We either have an end of
56  * medium condition or worse, and error condition.
57  * Attempt to "recover" by obtaining a new Volume.
58  *
59  * Here are a few things to know:
60  *  dcr->VolCatInfo contains the info on the "current" tape for this job.
61  *  dev->VolCatInfo contains the info on the tape in the drive.
62  *    The tape in the drive could have changed several times since
63  *    the last time the job used it (jcr->VolCatInfo).
64  *  dcr->VolumeName is the name of the current/desired tape in the drive.
65  *
66  * We enter with device locked, and
67  *     exit with device locked.
68  *
69  * Note, we are called only from one place in block.c for the daemons.
70  *     The btape utility calls it from btape.c.
71  *
72  *  Returns: true  on success
73  *           false on failure
74  */
75 bool fixup_device_block_write_error(DCR *dcr, int retries)
76 {
77    char PrevVolName[MAX_NAME_LENGTH];
78    DEV_BLOCK *block = dcr->block;
79    DEV_BLOCK *ameta_block = dcr->ameta_block;
80    DEV_BLOCK *adata_block = dcr->adata_block;
81    char b1[30], b2[30];
82    time_t wait_time;
83    char dt[MAX_TIME_LENGTH];
84    JCR *jcr = dcr->jcr;
85    DEVICE *dev;
86    int blocked;              /* save any previous blocked status */
87    bool ok = false;
88    bool save_adata = dcr->dev->adata;
89
90    Enter(100);
91    if (save_adata) {
92       dcr->set_ameta();      /* switch to working with ameta */
93    }
94    dev = dcr->dev;
95    blocked = dev->blocked();
96
97    wait_time = time(NULL);
98
99    /*
100     * If we are blocked at entry, unblock it, and set our own block status
101     */
102    if (blocked != BST_NOT_BLOCKED) {
103       unblock_device(dev);
104    }
105    block_device(dev, BST_DOING_ACQUIRE);
106
107    /* Continue unlocked, but leave BLOCKED */
108    dev->Unlock();
109
110    bstrncpy(PrevVolName, dev->getVolCatName(), sizeof(PrevVolName));
111    bstrncpy(dev->VolHdr.PrevVolumeName, PrevVolName, sizeof(dev->VolHdr.PrevVolumeName));
112
113    /* create temporary block, that will be released at the end, current blocks
114     * have been saved in local DEV_BLOCK above and will be restored before to
115     * leave the function
116     */
117    dev->new_dcr_blocks(dcr);
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    Dmsg1(150, "set_unload dev=%s\n", dev->print_name());
126    dev->set_unload();
127
128    /* Clear DCR Start/End Block/File positions */
129    dcr->VolFirstIndex = dcr->VolLastIndex = 0;
130    dcr->StartAddr = dcr->EndAddr = 0;
131    dcr->VolMediaId = 0;
132    dcr->WroteVol = false;
133
134    if (!dcr->mount_next_write_volume()) {
135       dev->free_dcr_blocks(dcr);
136       dcr->block = block;
137       dcr->ameta_block = ameta_block;
138       dcr->adata_block = adata_block;
139       dev->Lock();
140       goto bail_out;
141    }
142    Dmsg2(150, "must_unload=%d dev=%s\n", dev->must_unload(), dev->print_name());
143
144    dev->notify_newvol_in_attached_dcrs(dcr->VolumeName);
145    dev->Lock();                    /* lock again */
146
147    dev->VolCatInfo.VolCatJobs++;              /* increment number of jobs on vol */
148    if (!dir_update_volume_info(dcr, false, false)) { /* send Volume info to Director */
149       goto bail_out;
150    }
151
152    Jmsg(jcr, M_INFO, 0, _("New volume \"%s\" mounted on device %s at %s.\n"),
153       dcr->VolumeName, dev->print_name(), bstrftime(dt, sizeof(dt), time(NULL)));
154
155    /*
156     * If this is a new tape, the label_blk will contain the
157     *  label, so write it now. If this is a previously
158     *  used tape, mount_next_write_volume() will return an
159     *  empty label_blk, and nothing will be written.
160     */
161    Dmsg0(190, "write label block to dev\n");
162    if (!dcr->write_block_to_dev()) {
163       berrno be;
164       Pmsg1(0, _("write_block_to_device Volume label failed. ERR=%s"),
165         be.bstrerror(dev->dev_errno));
166       dev->free_dcr_blocks(dcr);
167       dcr->block = block;
168       dcr->ameta_block = ameta_block;
169       dcr->adata_block = adata_block;
170       goto bail_out;
171    }
172    dev->free_dcr_blocks(dcr);
173    dcr->block = block;
174    dcr->ameta_block = ameta_block;
175    dcr->adata_block = adata_block;
176
177    /* Clear NewVol now because dir_get_volume_info() already done */
178    jcr->dcr->NewVol = false;
179    set_new_volume_parameters(dcr);
180
181    jcr->run_time += time(NULL) - wait_time; /* correct run time for mount wait */
182
183    /* Write overflow block to device */
184    Dmsg0(190, "Write overflow block to dev\n");
185    if (save_adata) {
186       dcr->set_adata();      /* try to write block we entered with */
187    }
188    if (!dcr->write_block_to_dev()) {
189       berrno be;
190       Dmsg1(0, _("write_block_to_device overflow block failed. ERR=%s"),
191         be.bstrerror(dev->dev_errno));
192       /* Note: recursive call */
193       if (retries-- <= 0 || !fixup_device_block_write_error(dcr, retries)) {
194          Jmsg2(jcr, M_FATAL, 0,
195               _("Catastrophic error. Cannot write overflow block to device %s. ERR=%s"),
196               dev->print_name(), be.bstrerror(dev->dev_errno));
197          goto bail_out;
198       }
199    }
200    ok = true;
201
202 bail_out:
203    if (save_adata) {
204       dcr->set_ameta();   /* Do unblock ... on ameta */
205    }
206    /*
207     * At this point, the device is locked and blocked.
208     * Unblock the device, restore any entry blocked condition, then
209     *   return leaving the device locked (as it was on entry).
210     */
211    unblock_device(dev);
212    if (blocked != BST_NOT_BLOCKED) {
213       block_device(dev, blocked);
214    }
215    if (save_adata) {
216       dcr->set_adata();      /* switch back to what we entered with */
217    }
218    return ok;                               /* device locked */
219 }
220
221 void set_start_vol_position(DCR *dcr)
222 {
223    DEVICE *dev = dcr->dev;
224    /* Set new start position */
225    if (dev->is_tape()) {
226       dcr->StartAddr = dcr->EndAddr = dev->get_full_addr();
227    } else {
228       if (dev->adata) {
229          dev = dcr->ameta_dev;
230       }
231       /*
232        * Note: we only update the DCR values for ameta blocks
233        *  because all the indexing (JobMedia) is done with
234        *  ameta blocks/records, which may point to adata.
235        */
236       dcr->StartAddr = dcr->EndAddr = dev->get_full_addr();
237    }
238 }
239
240 /*
241  * We have a new Volume mounted, so reset the Volume parameters
242  *  concerning this job.  The global changes were made earlier
243  *  in the dev structure.
244  */
245 void set_new_volume_parameters(DCR *dcr)
246 {
247    JCR *jcr = dcr->jcr;
248    Dmsg1(40, "set_new_volume_parameters dev=%s\n", dcr->dev->print_name());
249    if (dcr->NewVol) {
250       while (dcr->VolumeName[0] == 0) {
251          int retries = 5;
252          wait_for_device(dcr, retries);
253       }
254       if (dir_get_volume_info(dcr, dcr->VolumeName, GET_VOL_INFO_FOR_WRITE)) {
255          dcr->dev->clear_wait();
256       } else {
257          Dmsg1(40, "getvolinfo failed. No new Vol: %s", jcr->errmsg);
258       }
259    }
260    set_new_file_parameters(dcr);
261    jcr->NumWriteVolumes++;
262    dcr->NewVol = false;
263 }
264
265 /*
266  * We are now in a new Volume file, so reset the Volume parameters
267  *  concerning this job.  The global changes were made earlier
268  *  in the dev structure.
269  */
270 void set_new_file_parameters(DCR *dcr)
271 {
272    set_start_vol_position(dcr);
273
274    /* Reset indicies */
275    Dmsg3(1000, "Reset indices Vol=%s were: FI=%d LI=%d\n", dcr->VolumeName,
276       dcr->VolFirstIndex, dcr->VolLastIndex);
277    dcr->VolFirstIndex = 0;
278    dcr->VolLastIndex = 0;
279    dcr->NewFile = false;
280    dcr->WroteVol = false;
281 }
282
283
284
285 /*
286  *   First Open of the device. Expect dev to already be initialized.
287  *
288  *   This routine is used only when the Storage daemon starts
289  *   and always_open is set, and in the stand-alone utility
290  *   routines such as bextract.
291  *
292  *   Note, opening of a normal file is deferred to later so
293  *    that we can get the filename; the device_name for
294  *    a file is the directory only.
295  *
296  *   Returns: false on failure
297  *            true  on success
298  */
299 bool first_open_device(DCR *dcr)
300 {
301    DEVICE *dev = dcr->dev;
302    bool ok = true;
303
304    Dmsg0(120, "start open_output_device()\n");
305    if (!dev) {
306       return false;
307    }
308
309    dev->rLock(false);
310
311    /* Defer opening files */
312    if (!dev->is_tape()) {
313       Dmsg0(129, "Device is file, deferring open.\n");
314       goto bail_out;
315    }
316
317    Dmsg0(129, "Opening device.\n");
318    if (!dev->open_device(dcr, OPEN_READ_ONLY)) {
319       Jmsg1(NULL, M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg);
320       ok = false;
321       goto bail_out;
322    }
323    Dmsg1(129, "open dev %s OK\n", dev->print_name());
324
325 bail_out:
326    dev->rUnlock();
327    return ok;
328 }