]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/device.c
11Apr07
[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 plus additions
11    that are listed 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 #ifdef SD_DEBUG_LOCK
63 const int dbglvl = 0;
64 #else
65 const int dbglvl = 500;
66 #endif
67
68
69 /* Forward referenced functions */
70
71 /*
72  * This is the dreaded moment. We either have an end of
73  * medium condition or worse, and error condition.
74  * Attempt to "recover" by obtaining a new Volume.
75  *
76  * Here are a few things to know:
77  *  dcr->VolCatInfo contains the info on the "current" tape for this job.
78  *  dev->VolCatInfo contains the info on the tape in the drive.
79  *    The tape in the drive could have changed several times since
80  *    the last time the job used it (jcr->VolCatInfo).
81  *  dcr->VolumeName is the name of the current/desired tape in the drive.
82  *
83  * We enter with device locked, and
84  *     exit with device locked.
85  *
86  * Note, we are called only from one place in block.c for the daemons.  
87  *     The btape utility calls it from btape.c.
88  *
89  *  Returns: true  on success
90  *           false on failure
91  */
92 bool fixup_device_block_write_error(DCR *dcr)
93 {
94    char PrevVolName[MAX_NAME_LENGTH];
95    DEV_BLOCK *label_blk;
96    DEV_BLOCK *block = dcr->block;
97    char b1[30], b2[30];
98    time_t wait_time;
99    char dt[MAX_TIME_LENGTH];
100    JCR *jcr = dcr->jcr;
101    DEVICE *dev = dcr->dev;
102
103    wait_time = time(NULL);
104
105    Dmsg0(100, "Enter fixup_device_block_write_error\n");
106
107    block_device(dev, BST_DOING_ACQUIRE);
108    /* Unlock, but leave BLOCKED */
109    dev->dunlock();
110
111    bstrncpy(PrevVolName, dev->VolCatInfo.VolCatName, sizeof(PrevVolName));
112    bstrncpy(dev->VolHdr.PrevVolumeName, PrevVolName, sizeof(dev->VolHdr.PrevVolumeName));
113
114    label_blk = new_block(dev);
115    dcr->block = label_blk;
116
117    /* Inform User about end of medium */
118    Jmsg(jcr, M_INFO, 0, _("End of medium on Volume \"%s\" Bytes=%s Blocks=%s at %s.\n"),
119         PrevVolName, edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, b1),
120         edit_uint64_with_commas(dev->VolCatInfo.VolCatBlocks, b2),
121         bstrftime(dt, sizeof(dt), time(NULL)));
122
123    if (!mount_next_write_volume(dcr, 1)) {
124       free_block(label_blk);
125       dcr->block = block;
126       dev->dlock();  
127       unblock_device(dev);
128       return false;                /* device locked */
129    }
130    dev->dlock();                    /* lock again */
131
132    dev->VolCatInfo.VolCatJobs++;              /* increment number of jobs on vol */
133    dir_update_volume_info(dcr, false);        /* send Volume info to Director */
134
135    Jmsg(jcr, M_INFO, 0, _("New volume \"%s\" mounted on device %s at %s.\n"),
136       dcr->VolumeName, dev->print_name(), bstrftime(dt, sizeof(dt), time(NULL)));
137
138    /*
139     * If this is a new tape, the label_blk will contain the
140     *  label, so write it now. If this is a previously
141     *  used tape, mount_next_write_volume() will return an
142     *  empty label_blk, and nothing will be written.
143     */
144    Dmsg0(190, "write label block to dev\n");
145    if (!write_block_to_dev(dcr)) {
146       berrno be;
147       Pmsg1(0, _("write_block_to_device Volume label failed. ERR=%s"),
148         be.strerror(dev->dev_errno));
149       free_block(label_blk);
150       dcr->block = block;
151       unblock_device(dev);
152       return false;                /* device locked */
153    }
154    free_block(label_blk);
155    dcr->block = block;
156
157    /*
158     * Walk through all attached jcrs indicating the volume has changed
159     */
160    Dmsg1(100, "Walk attached dcrs. Volume=%s\n", dev->VolCatInfo.VolCatName);
161    DCR *mdcr;
162    foreach_dlist(mdcr, dev->attached_dcrs) {
163       JCR *mjcr = mdcr->jcr;
164       if (mjcr->JobId == 0) {
165          continue;                 /* ignore console */
166       }
167       mdcr->NewVol = true;
168       if (jcr != mjcr) {
169          bstrncpy(mdcr->VolumeName, dcr->VolumeName, sizeof(mdcr->VolumeName));
170       }
171    }
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 (!write_block_to_dev(dcr)) {
182       berrno be;
183       Pmsg1(0, _("write_block_to_device overflow block failed. ERR=%s"),
184         be.strerror(dev->dev_errno));
185       unblock_device(dev);
186       return false;                /* device locked */
187    }
188
189    unblock_device(dev);
190    return true;                             /* device locked */
191 }
192
193 /*
194  * We have a new Volume mounted, so reset the Volume parameters
195  *  concerning this job.  The global changes were made earlier
196  *  in the dev structure.
197  */
198 void set_new_volume_parameters(DCR *dcr)
199 {
200    JCR *jcr = dcr->jcr;
201    DEVICE *dev = dcr->dev;
202    if (dcr->NewVol && !dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE)) {
203       Jmsg1(jcr, M_ERROR, 0, "%s", jcr->errmsg);
204    }
205    /* Set new start/end positions */
206    if (dev->is_tape()) {
207       dcr->StartBlock = dev->block_num;
208       dcr->StartFile = dev->file;
209    } else {
210       dcr->StartBlock = (uint32_t)dev->file_addr;
211       dcr->StartFile  = (uint32_t)(dev->file_addr >> 32);
212    }
213    /* Reset indicies */
214    dcr->VolFirstIndex = 0;
215    dcr->VolLastIndex = 0;
216    jcr->NumWriteVolumes++;
217    dcr->NewVol = false;
218    dcr->WroteVol = false;
219 }
220
221 /*
222  * We are now in a new Volume file, so reset the Volume parameters
223  *  concerning this job.  The global changes were made earlier
224  *  in the dev structure.
225  */
226 void set_new_file_parameters(DCR *dcr)
227 {
228    DEVICE *dev = dcr->dev;
229
230    /* Set new start/end positions */
231    if (dev->is_tape()) {
232       dcr->StartBlock = dev->block_num;
233       dcr->StartFile = dev->file;
234    } else {
235       dcr->StartBlock = (uint32_t)dev->file_addr;
236       dcr->StartFile  = (uint32_t)(dev->file_addr >> 32);
237    }
238    /* Reset indicies */
239    dcr->VolFirstIndex = 0;
240    dcr->VolLastIndex = 0;
241    dcr->NewFile = false;
242    dcr->WroteVol = false;
243 }
244
245
246
247 /*
248  *   First Open of the device. Expect dev to already be initialized.
249  *
250  *   This routine is used only when the Storage daemon starts
251  *   and always_open is set, and in the stand-alone utility
252  *   routines such as bextract.
253  *
254  *   Note, opening of a normal file is deferred to later so
255  *    that we can get the filename; the device_name for
256  *    a file is the directory only.
257  *
258  *   Returns: false on failure
259  *            true  on success
260  */
261 bool first_open_device(DCR *dcr)
262 {
263    DEVICE *dev = dcr->dev;
264    bool ok = true;
265
266    Dmsg0(120, "start open_output_device()\n");
267    if (!dev) {
268       return false;
269    }
270
271    dev->r_dlock();
272
273    /* Defer opening files */
274    if (!dev->is_tape()) {
275       Dmsg0(129, "Device is file, deferring open.\n");
276       goto bail_out;
277    }
278
279     int mode;
280     if (dev->has_cap(CAP_STREAM)) {
281        mode = OPEN_WRITE_ONLY;
282     } else {
283        mode = OPEN_READ_ONLY;
284     }
285    Dmsg0(129, "Opening device.\n");
286    if (dev->open(dcr, mode) < 0) {
287       Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg);
288       ok = false;
289       goto bail_out;
290    }
291    Dmsg1(129, "open dev %s OK\n", dev->print_name());
292
293 bail_out:
294    dev->dunlock();
295    return ok;
296 }
297
298 /*
299  * Make sure device is open, if not do so
300  */
301 bool open_device(DCR *dcr)
302 {
303    DEVICE *dev = dcr->dev;
304    /* Open device */
305    int mode;
306    if (dev->has_cap(CAP_STREAM)) {
307       mode = OPEN_WRITE_ONLY;
308    } else {
309       mode = OPEN_READ_WRITE;
310    }
311    if (dev->open(dcr, mode) < 0) {
312       /* If polling, ignore the error */
313       /* If DVD, also ignore the error, very often you cannot open the device
314        * (when there is no DVD, or when the one inserted is a wrong one) */
315       if (!dev->poll && !dev->is_dvd() && !dev->is_removable()) {
316          Jmsg2(dcr->jcr, M_FATAL, 0, _("Unable to open device %s: ERR=%s\n"),
317             dev->print_name(), dev->bstrerror());
318          Pmsg2(000, _("Unable to open archive %s: ERR=%s\n"), 
319             dev->print_name(), dev->bstrerror());
320       }
321       return false;
322    }
323    return true;
324 }
325
326 /*
327  * Find which JobId corresponds to the current thread
328  */
329 uint32_t get_jobid_from_tid()
330 {
331    JCR *jcr;
332    uint32_t JobId = 0;
333    foreach_jcr(jcr) {
334       if (pthread_equal(jcr->my_thread_id, pthread_self())) {
335          JobId = (uint32_t)jcr->JobId;
336          break;
337       }
338    }
339    endeach_jcr(jcr);
340    return JobId;
341 }
342
343 /*
344  * Check if the device is blocked or not
345  */
346 bool is_device_unmounted(DEVICE *dev)
347 {
348    bool stat;
349    int blocked = dev->blocked();
350    stat = (blocked == BST_UNMOUNTED) ||
351           (blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP);
352    return stat;
353 }
354
355 void DEVICE::_dlock(const char *file, int line)
356 {
357    Dmsg4(sd_dbglvl, "dlock from %s:%d precnt=%d JobId=%u\n", file, line,
358          m_count, get_jobid_from_tid()); 
359    /* Note, this *really* should be protected by a mutex, but
360     *  since it is only debug code we don't worry too much.  
361     */
362    if (m_count > 0 && pthread_equal(m_pid, pthread_self())) {
363       Dmsg2(sd_dbglvl, "DEADLOCK !!!!!!!!!! from %s:%d\n", file, line);
364    }
365    P(m_mutex);
366    m_pid = pthread_self();
367    m_count++; 
368 }
369
370 void DEVICE::_dunlock(const char *file, int line)
371 {
372    m_count--; 
373    Dmsg4(sd_dbglvl, "dunlock from %s:%d postcnt=%d JobId=%u\n", file, line,
374          m_count, get_jobid_from_tid()); 
375    V(m_mutex);   
376 }
377
378 #ifdef SD_DEBUG_LOCK
379 void DEVICE::_r_dunlock(const char *file, int line)
380 {
381    this->_dunlock(file, line);
382 }
383 #else
384 void DEVICE::r_dunlock()
385 {
386    this->dunlock();
387 }
388 #endif
389
390
391 /*
392  * This is a recursive lock that checks if the device is blocked.
393  *
394  * When blocked is set, all threads EXCEPT thread with id no_wait_id
395  * must wait. The no_wait_id thread is out obtaining a new volume
396  * and preparing the label.
397  */
398 #ifdef SD_DEBUG_LOCK
399 void DEVICE::_r_dlock(const char *file, int line)
400 #else
401 void DEVICE::r_dlock()
402 #endif
403 {
404    int stat;
405 #ifdef SD_DEBUG_LOCK
406    Dmsg4(dbglvl, "r_dlock blked=%s from %s:%d JobId=%u\n", this->print_blocked(),
407          file, line, get_jobid_from_tid());
408 #else
409    Dmsg1dbglvl, "reclock blked=%s\n", this->print_blocked());
410 #endif
411    this->dlock();   
412    if (this->blocked() && !pthread_equal(this->no_wait_id, pthread_self())) {
413       this->num_waiting++;             /* indicate that I am waiting */
414       while (this->blocked()) {
415          Dmsg3(dbglvl, "r_dlock blked=%s no_wait=%p me=%p\n", this->print_blocked(),
416                this->no_wait_id, pthread_self());
417          if ((stat = pthread_cond_wait(&this->wait, &m_mutex)) != 0) {
418             berrno be;
419             this->dunlock();
420             Emsg1(M_ABORT, 0, _("pthread_cond_wait failure. ERR=%s\n"),
421                be.strerror(stat));
422          }
423       }
424       this->num_waiting--;             /* no longer waiting */
425    }
426 }
427
428 /*
429  * Block all other threads from using the device
430  *  Device must already be locked.  After this call,
431  *  the device is blocked to any thread calling dev->r_lock(),
432  *  but the device is not locked (i.e. no P on device).  Also,
433  *  the current thread can do slip through the dev->r_lock()
434  *  calls without blocking.
435  */
436 void _block_device(const char *file, int line, DEVICE *dev, int state)
437 {
438    Dmsg3(dbglvl, "block set %d from %s:%d\n", state, file, line);
439
440    ASSERT(dev->blocked() == BST_NOT_BLOCKED);
441    dev->set_blocked(state);           /* make other threads wait */
442    dev->no_wait_id = pthread_self();  /* allow us to continue */
443 }
444
445 /*
446  * Unblock the device, and wake up anyone who went to sleep.
447  * Enter: device locked
448  * Exit:  device locked
449  */
450 void _unblock_device(const char *file, int line, DEVICE *dev)
451 {
452    Dmsg3(dbglvl, "unblock %s from %s:%d\n", dev->print_blocked(), file, line);
453    ASSERT(dev->blocked());
454    dev->set_blocked(BST_NOT_BLOCKED);
455    dev->no_wait_id = 0;
456    if (dev->num_waiting > 0) {
457       pthread_cond_broadcast(&dev->wait); /* wake them up */
458    }
459 }
460
461 /*
462  * Enter with device locked and blocked
463  * Exit with device unlocked and blocked by us.
464  */
465 void _steal_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold, int state)
466 {
467
468    Dmsg3(dbglvl, "steal lock. old=%s from %s:%d\n", dev->print_blocked(),
469       file, line);
470    hold->dev_blocked = dev->blocked();
471    hold->dev_prev_blocked = dev->dev_prev_blocked;
472    hold->no_wait_id = dev->no_wait_id;
473    dev->set_blocked(state);
474    Dmsg1(dbglvl, "steal lock. new=%s\n", dev->print_blocked());
475    dev->no_wait_id = pthread_self();
476    dev->dunlock();
477 }
478
479 /*
480  * Enter with device blocked by us but not locked
481  * Exit with device locked, and blocked by previous owner
482  */
483 void _give_back_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold)
484 {
485    Dmsg3(dbglvl, "return lock. old=%s from %s:%d\n",
486       dev->print_blocked(), file, line);
487    dev->dlock();
488    dev->set_blocked(hold->dev_blocked);
489    dev->dev_prev_blocked = hold->dev_prev_blocked;
490    dev->no_wait_id = hold->no_wait_id;
491    Dmsg1(dbglvl, "return lock. new=%s\n", dev->print_blocked());
492    if (dev->num_waiting > 0) {
493       pthread_cond_broadcast(&dev->wait); /* wake them up */
494    }
495 }