]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/device.c
Big backport from Enterprise
[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    dev->new_dcr_blocks(dcr);
114
115    /* Inform User about end of medium */
116    Jmsg(jcr, M_INFO, 0, _("End of medium on Volume \"%s\" Bytes=%s Blocks=%s at %s.\n"),
117         PrevVolName, edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, b1),
118         edit_uint64_with_commas(dev->VolCatInfo.VolCatBlocks, b2),
119         bstrftime(dt, sizeof(dt), time(NULL)));
120
121    Dmsg1(150, "set_unload dev=%s\n", dev->print_name());
122    dev->set_unload();
123
124    /* Clear DCR Start/End Block/File positions */
125    dcr->VolFirstIndex = dcr->VolLastIndex = 0;
126    dcr->StartAddr = dcr->EndAddr = 0;
127    dcr->VolMediaId = 0;
128    dcr->WroteVol = false;
129
130    if (!dcr->mount_next_write_volume()) {
131       dev->free_dcr_blocks(dcr);
132       dcr->block = block;
133       dcr->ameta_block = ameta_block;
134       dcr->adata_block = adata_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    if (!dir_update_volume_info(dcr, false, false)) { /* send Volume info to Director */
145       goto bail_out;
146    }
147
148    Jmsg(jcr, M_INFO, 0, _("New volume \"%s\" mounted on device %s at %s.\n"),
149       dcr->VolumeName, dev->print_name(), bstrftime(dt, sizeof(dt), time(NULL)));
150
151    /*
152     * If this is a new tape, the label_blk will contain the
153     *  label, so write it now. If this is a previously
154     *  used tape, mount_next_write_volume() will return an
155     *  empty label_blk, and nothing will be written.
156     */
157    Dmsg0(190, "write label block to dev\n");
158    if (!dcr->write_block_to_dev()) {
159       berrno be;
160       Pmsg1(0, _("write_block_to_device Volume label failed. ERR=%s"),
161         be.bstrerror(dev->dev_errno));
162       dev->free_dcr_blocks(dcr);
163       dcr->block = block;
164       dcr->ameta_block = ameta_block;
165       dcr->adata_block = adata_block;
166       goto bail_out;
167    }
168    dev->free_dcr_blocks(dcr);
169    dcr->block = block;
170    dcr->ameta_block = ameta_block;
171    dcr->adata_block = adata_block;
172
173    /* Clear NewVol now because dir_get_volume_info() already done */
174    jcr->dcr->NewVol = false;
175    set_new_volume_parameters(dcr);
176
177    jcr->run_time += time(NULL) - wait_time; /* correct run time for mount wait */
178
179    /* Write overflow block to device */
180    Dmsg0(190, "Write overflow block to dev\n");
181    if (save_adata) {
182       dcr->set_adata();      /* try to write block we entered with */
183    }
184    if (!dcr->write_block_to_dev()) {
185       berrno be;
186       Dmsg1(0, _("write_block_to_device overflow block failed. ERR=%s"),
187         be.bstrerror(dev->dev_errno));
188       /* Note: recursive call */
189       if (retries-- <= 0 || !fixup_device_block_write_error(dcr, retries)) {
190          Jmsg2(jcr, M_FATAL, 0,
191               _("Catastrophic error. Cannot write overflow block to device %s. ERR=%s"),
192               dev->print_name(), be.bstrerror(dev->dev_errno));
193          goto bail_out;
194       }
195    }
196    ok = true;
197
198 bail_out:
199    if (save_adata) {
200       dcr->set_ameta();   /* Do unblock ... on ameta */
201    }
202    /*
203     * At this point, the device is locked and blocked.
204     * Unblock the device, restore any entry blocked condition, then
205     *   return leaving the device locked (as it was on entry).
206     */
207    unblock_device(dev);
208    if (blocked != BST_NOT_BLOCKED) {
209       block_device(dev, blocked);
210    }
211    if (save_adata) {
212       dcr->set_adata();      /* switch back to what we entered with */
213    }
214    return ok;                               /* device locked */
215 }
216
217 void set_start_vol_position(DCR *dcr)
218 {
219    DEVICE *dev = dcr->dev;
220    /* Set new start position */
221    if (dev->is_tape()) {
222       dcr->StartAddr = dcr->EndAddr = dev->get_full_addr();
223    } else {
224       if (dev->adata) {
225          dev = dcr->ameta_dev;
226       }
227       /*
228        * Note: we only update the DCR values for ameta blocks
229        *  because all the indexing (JobMedia) is done with
230        *  ameta blocks/records, which may point to adata.
231        */
232       dcr->StartAddr = dcr->EndAddr = dev->get_full_addr();
233    }
234 }
235
236 /*
237  * We have a new Volume mounted, so reset the Volume parameters
238  *  concerning this job.  The global changes were made earlier
239  *  in the dev structure.
240  */
241 void set_new_volume_parameters(DCR *dcr)
242 {
243    JCR *jcr = dcr->jcr;
244    Dmsg1(40, "set_new_volume_parameters dev=%s\n", dcr->dev->print_name());
245    if (dcr->NewVol) {
246       while (dcr->VolumeName[0] == 0) {
247          int retries = 5;
248          wait_for_device(dcr, retries);
249       }
250       if (dir_get_volume_info(dcr, dcr->VolumeName, GET_VOL_INFO_FOR_WRITE)) {
251          dcr->dev->clear_wait();
252       } else {
253          Dmsg1(40, "getvolinfo failed. No new Vol: %s", jcr->errmsg);
254       }
255    }
256    set_new_file_parameters(dcr);
257    jcr->NumWriteVolumes++;
258    dcr->NewVol = false;
259 }
260
261 /*
262  * We are now in a new Volume file, so reset the Volume parameters
263  *  concerning this job.  The global changes were made earlier
264  *  in the dev structure.
265  */
266 void set_new_file_parameters(DCR *dcr)
267 {
268    set_start_vol_position(dcr);
269
270    /* Reset indicies */
271    Dmsg3(1000, "Reset indices Vol=%s were: FI=%d LI=%d\n", dcr->VolumeName,
272       dcr->VolFirstIndex, dcr->VolLastIndex);
273    dcr->VolFirstIndex = 0;
274    dcr->VolLastIndex = 0;
275    dcr->NewFile = false;
276    dcr->WroteVol = false;
277 }
278
279
280
281 /*
282  *   First Open of the device. Expect dev to already be initialized.
283  *
284  *   This routine is used only when the Storage daemon starts
285  *   and always_open is set, and in the stand-alone utility
286  *   routines such as bextract.
287  *
288  *   Note, opening of a normal file is deferred to later so
289  *    that we can get the filename; the device_name for
290  *    a file is the directory only.
291  *
292  *   Returns: false on failure
293  *            true  on success
294  */
295 bool first_open_device(DCR *dcr)
296 {
297    DEVICE *dev = dcr->dev;
298    bool ok = true;
299
300    Dmsg0(120, "start open_output_device()\n");
301    if (!dev) {
302       return false;
303    }
304
305    dev->rLock(false);
306
307    /* Defer opening files */
308    if (!dev->is_tape()) {
309       Dmsg0(129, "Device is file, deferring open.\n");
310       goto bail_out;
311    }
312
313    Dmsg0(129, "Opening device.\n");
314    if (!dev->open_device(dcr, OPEN_READ_ONLY)) {
315       Jmsg1(NULL, M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg);
316       ok = false;
317       goto bail_out;
318    }
319    Dmsg1(129, "open dev %s OK\n", dev->print_name());
320
321 bail_out:
322    dev->rUnlock();
323    return ok;
324 }