]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/device.c
Backport from BEE
[bacula/bacula] / bacula / src / stored / device.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2000-2014 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from many
7    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    Bacula® is a registered trademark of Kern Sibbald.
15 */
16 /*
17  *
18  *  Higher Level Device routines.
19  *  Knows about Bacula tape labels and such
20  *
21  *  NOTE! In general, subroutines that have the word
22  *        "device" in the name do locking.  Subroutines
23  *        that have the word "dev" in the name do not
24  *        do locking.  Thus if xxx_device() calls
25  *        yyy_dev(), all is OK, but if xxx_device()
26  *        calls yyy_device(), everything will hang.
27  *        Obviously, no zzz_dev() is allowed to call
28  *        a www_device() or everything falls apart.
29  *
30  * Concerning the routines dev->rLock()() and block_device()
31  *  see the end of this module for details.  In general,
32  *  blocking a device leaves it in a state where all threads
33  *  other than the current thread block when they attempt to
34  *  lock the device. They remain suspended (blocked) until the device
35  *  is unblocked. So, a device is blocked during an operation
36  *  that takes a long time (initialization, mounting a new
37  *  volume, ...) locking a device is done for an operation
38  *  that takes a short time such as writing data to the
39  *  device.
40  *
41  *
42  *   Kern Sibbald, MM, MMI
43  *
44  */
45
46 #include "bacula.h"                   /* pull in global headers */
47 #ifdef HAVE_SYS_STATVFS_H
48 #include <sys/statvfs.h>
49 #else
50 #define statvfs statfs
51 #endif
52 /* statvfs.h defines ST_APPEND, which is also used by Bacula */
53 #undef ST_APPEND
54
55 #include "stored.h"                   /* pull in Storage Deamon headers */
56
57
58 /* Forward referenced functions */
59
60 /*
61  * This is the dreaded moment. We either have an end of
62  * medium condition or worse, and error condition.
63  * Attempt to "recover" by obtaining a new Volume.
64  *
65  * Here are a few things to know:
66  *  dcr->VolCatInfo contains the info on the "current" tape for this job.
67  *  dev->VolCatInfo contains the info on the tape in the drive.
68  *    The tape in the drive could have changed several times since
69  *    the last time the job used it (jcr->VolCatInfo).
70  *  dcr->VolumeName is the name of the current/desired tape in the drive.
71  *
72  * We enter with device locked, and
73  *     exit with device locked.
74  *
75  * Note, we are called only from one place in block.c for the daemons.
76  *     The btape utility calls it from btape.c.
77  *
78  *  Returns: true  on success
79  *           false on failure
80  */
81 bool fixup_device_block_write_error(DCR *dcr, int retries)
82 {
83    char PrevVolName[MAX_NAME_LENGTH];
84    DEV_BLOCK *label_blk;
85    DEV_BLOCK *block;
86    char b1[30], b2[30];
87    time_t wait_time;
88    char dt[MAX_TIME_LENGTH];
89    JCR *jcr = dcr->jcr;
90    DEVICE *dev;
91    int blocked;              /* save any previous blocked status */
92    bool ok = false;
93
94    dev = dcr->dev;
95    blocked = dev->blocked();
96    block = dcr->block;
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->Unlock();
112
113    bstrncpy(PrevVolName, dev->getVolCatName(), 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    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->StartBlock = dcr->EndBlock = 0;
130    dcr->StartFile  = dcr->EndFile = 0;
131
132    if (!dcr->mount_next_write_volume()) {
133       free_block(label_blk);
134       dcr->block = block;
135       dev->Lock();
136       goto bail_out;
137    }
138    Dmsg2(150, "must_unload=%d dev=%s\n", dev->must_unload(), dev->print_name());
139
140    dev->notify_newvol_in_attached_dcrs(dcr->VolumeName);
141    dev->Lock();                    /* lock again */
142
143    dev->VolCatInfo.VolCatJobs++;              /* increment number of jobs on vol */
144    dir_update_volume_info(dcr, false, false); /* send Volume info to Director */
145
146    Jmsg(jcr, M_INFO, 0, _("New volume \"%s\" mounted on device %s at %s.\n"),
147       dcr->VolumeName, dev->print_name(), bstrftime(dt, sizeof(dt), time(NULL)));
148
149    /*
150     * If this is a new tape, the label_blk will contain the
151     *  label, so write it now. If this is a previously
152     *  used tape, mount_next_write_volume() will return an
153     *  empty label_blk, and nothing will be written.
154     */
155    Dmsg0(190, "write label block to dev\n");
156    if (!dcr->write_block_to_dev()) {
157       berrno be;
158       Pmsg1(0, _("write_block_to_device Volume label failed. ERR=%s"),
159         be.bstrerror(dev->dev_errno));
160       free_block(label_blk);
161       dcr->block = block;
162       goto bail_out;
163    }
164    free_block(label_blk);
165    dcr->block = block;
166
167    /* Clear NewVol now because dir_get_volume_info() already done */
168    jcr->dcr->NewVol = false;
169    set_new_volume_parameters(dcr);
170
171    jcr->run_time += time(NULL) - wait_time; /* correct run time for mount wait */
172
173    /* Write overflow block to device */
174    Dmsg0(190, "Write overflow block to dev\n");
175    if (!dcr->write_block_to_dev()) {
176       berrno be;
177       Dmsg1(0, _("write_block_to_device overflow block failed. ERR=%s"),
178         be.bstrerror(dev->dev_errno));
179       /* Note: recursive call */
180       if (retries-- <= 0 || !fixup_device_block_write_error(dcr, retries)) {
181          Jmsg2(jcr, M_FATAL, 0,
182               _("Catastrophic error. Cannot write overflow block to device %s. ERR=%s"),
183               dev->print_name(), be.bstrerror(dev->dev_errno));
184          goto bail_out;
185       }
186    }
187    ok = true;
188
189 bail_out:
190    /*
191     * At this point, the device is locked and blocked.
192     * Unblock the device, restore any entry blocked condition, then
193     *   return leaving the device locked (as it was on entry).
194     */
195    unblock_device(dev);
196    if (blocked != BST_NOT_BLOCKED) {
197       block_device(dev, blocked);
198    }
199    return ok;                               /* device locked */
200 }
201
202 void set_start_vol_position(DCR *dcr)
203 {
204    DEVICE *dev = dcr->dev;
205    /* Set new start position */
206    if (dev->is_tape()) {
207       dcr->StartBlock = dev->block_num;
208       dcr->StartFile = dev->file;
209    } else {
210       /*
211        * Note: we only update the DCR values for blocks
212        */
213       dcr->StartBlock = dcr->EndBlock = (uint32_t)dev->file_addr;
214       dcr->StartFile  = dcr->EndFile = (uint32_t)(dev->file_addr >> 32);
215    }
216 }
217
218 /*
219  * We have a new Volume mounted, so reset the Volume parameters
220  *  concerning this job.  The global changes were made earlier
221  *  in the dev structure.
222  */
223 void set_new_volume_parameters(DCR *dcr)
224 {
225    JCR *jcr = dcr->jcr;
226    Dmsg1(40, "set_new_volume_parameters dev=%s\n", dcr->dev->print_name());
227    if (dcr->NewVol) {
228       while (dcr->VolumeName[0] == 0) {
229          int retries = 5;
230          wait_for_device(dcr, retries);
231       }
232       if (dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE)) {
233          dcr->dev->clear_wait();
234       } else {
235          Dmsg1(40, "getvolinfo failed. No new Vol: %s", jcr->errmsg);
236       }
237    }
238    set_new_file_parameters(dcr);
239    jcr->NumWriteVolumes++;
240    dcr->NewVol = false;
241 }
242
243 /*
244  * We are now in a new Volume file, so reset the Volume parameters
245  *  concerning this job.  The global changes were made earlier
246  *  in the dev structure.
247  */
248 void set_new_file_parameters(DCR *dcr)
249 {
250    set_start_vol_position(dcr);
251
252    /* Reset indicies */
253    Dmsg3(1000, "Reset indices Vol=%s were: FI=%d LI=%d\n", dcr->VolumeName,
254       dcr->VolFirstIndex, dcr->VolLastIndex);
255    dcr->VolFirstIndex = 0;
256    dcr->VolLastIndex = 0;
257    dcr->NewFile = false;
258    dcr->WroteVol = false;
259 }
260
261
262
263 /*
264  *   First Open of the device. Expect dev to already be initialized.
265  *
266  *   This routine is used only when the Storage daemon starts
267  *   and always_open is set, and in the stand-alone utility
268  *   routines such as bextract.
269  *
270  *   Note, opening of a normal file is deferred to later so
271  *    that we can get the filename; the device_name for
272  *    a file is the directory only.
273  *
274  *   Returns: false on failure
275  *            true  on success
276  */
277 bool first_open_device(DCR *dcr)
278 {
279    DEVICE *dev = dcr->dev;
280    bool ok = true;
281
282    Dmsg0(120, "start open_output_device()\n");
283    if (!dev) {
284       return false;
285    }
286
287    dev->rLock(false);
288
289    /* Defer opening files */
290    if (!dev->is_tape()) {
291       Dmsg0(129, "Device is file, deferring open.\n");
292       goto bail_out;
293    }
294
295     int mode;
296     if (dev->has_cap(CAP_STREAM)) {
297        mode = OPEN_WRITE_ONLY;
298     } else {
299        mode = OPEN_READ_ONLY;
300     }
301    Dmsg0(129, "Opening device.\n");
302    if (!dev->open(dcr, mode)) {
303       Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg);
304       ok = false;
305       goto bail_out;
306    }
307    Dmsg1(129, "open dev %s OK\n", dev->print_name());
308
309 bail_out:
310    dev->rUnlock();
311    return ok;
312 }
313
314 /*
315  * Make sure device is open, if not do so
316  */
317 bool open_dev(DCR *dcr)
318 {
319    DEVICE *dev = dcr->dev;
320    /* Open device */
321    int mode;
322    if (dev->has_cap(CAP_STREAM)) {
323       mode = OPEN_WRITE_ONLY;
324    } else {
325       mode = OPEN_READ_WRITE;
326    }
327    if (!dev->open(dcr, mode)) {
328       /* If polling, ignore the error */
329       /* If DVD, also ignore the error, very often you cannot open the device
330        * (when there is no DVD, or when the one inserted is a wrong one) */
331       if (!dev->poll && !dev->is_dvd() && !dev->is_removable()) {
332          Jmsg2(dcr->jcr, M_FATAL, 0, _("Unable to open device %s: ERR=%s\n"),
333             dev->print_name(), dev->bstrerror());
334          Pmsg2(000, _("Unable to open archive %s: ERR=%s\n"),
335             dev->print_name(), dev->bstrerror());
336       }
337       return false;
338    }
339    return true;
340 }
341
342 /*
343  */
344 void DEVICE::updateVolCatBytes(uint64_t bytes)
345 {
346    DEVICE *dev;
347    Lock_VolCatInfo();
348    dev = this;
349    dev->VolCatInfo.VolCatAmetaBytes += bytes;
350    dev->VolCatInfo.VolCatBytes += bytes;
351    setVolCatInfo(false);
352    Unlock_VolCatInfo();
353 }
354
355 void DEVICE::updateVolCatBlocks(uint32_t blocks)
356 {
357    DEVICE *dev;
358    Lock_VolCatInfo();
359    dev = this;
360    dev->VolCatInfo.VolCatAmetaBlocks += blocks;
361    dev->VolCatInfo.VolCatBlocks += blocks;
362    setVolCatInfo(false);
363    Unlock_VolCatInfo();
364 }
365
366 void DEVICE::updateVolCatWrites(uint32_t writes)
367 {
368    DEVICE *dev;
369    Lock_VolCatInfo();
370    dev = this;
371    dev->VolCatInfo.VolCatAmetaWrites += writes;
372    dev->VolCatInfo.VolCatWrites += writes;
373    setVolCatInfo(false);
374    Unlock_VolCatInfo();
375 }
376
377 void DEVICE::updateVolCatReads(uint32_t reads)
378 {
379    DEVICE *dev;
380    Lock_VolCatInfo();
381    dev = this;
382    dev->VolCatInfo.VolCatAmetaReads += reads;
383    dev->VolCatInfo.VolCatReads += reads;
384    setVolCatInfo(false);
385    Unlock_VolCatInfo();
386 }
387
388 void DEVICE::updateVolCatReadBytes(uint64_t bytes)
389 {
390    DEVICE *dev;
391    Lock_VolCatInfo();
392    dev = this;
393    dev->VolCatInfo.VolCatAmetaRBytes += bytes;
394    dev->VolCatInfo.VolCatRBytes += bytes;
395    setVolCatInfo(false);
396    Unlock_VolCatInfo();
397 }
398
399 void DEVICE::set_nospace()
400 {
401    state |= ST_NOSPACE;
402 }
403
404 void DEVICE::clear_nospace()
405 {
406    state &= ~ST_NOSPACE;
407 }
408
409 /* Put device in append mode */
410 void DEVICE::set_append()
411 {
412    state &= ~(ST_NOSPACE|ST_READ|ST_EOT|ST_EOF|ST_WEOT);  /* remove EOF/EOT flags */
413    state |= ST_APPEND;
414 }
415
416 /* Clear append mode */
417 void DEVICE::clear_append()
418 {
419    state &= ~ST_APPEND;
420 }
421
422 /* Put device in read mode */
423 void DEVICE::set_read()
424 {
425    state &= ~(ST_APPEND|ST_EOT|ST_EOF|ST_WEOT);  /* remove EOF/EOT flags */
426    state |= ST_READ;
427 }
428
429 /* Clear read mode */
430 void DEVICE::clear_read()
431 {
432    state &= ~ST_READ;
433 }