]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/device.c
Insure that all the SD tools init the Autochanger
[bacula/bacula] / bacula / src / stored / device.c
1 /*
2  *
3  *  Higher Level Device routines.
4  *  Knows about Bacula tape labels and such
5  *
6  *  NOTE! In general, subroutines that have the word
7  *        "device" in the name do locking.  Subroutines
8  *        that have the word "dev" in the name do not
9  *        do locking.  Thus if xxx_device() calls
10  *        yyy_dev(), all is OK, but if xxx_device()
11  *        calls yyy_device(), everything will hang.
12  *        Obviously, no zzz_dev() is allowed to call
13  *        a www_device() or everything falls apart.
14  *
15  * Concerning the routines lock_device() and block_device()
16  *  see the end of this module for details.  In general,
17  *  blocking a device leaves it in a state where all threads
18  *  other than the current thread block when they attempt to
19  *  lock the device. They remain suspended (blocked) until the device
20  *  is unblocked. So, a device is blocked during an operation
21  *  that takes a long time (initialization, mounting a new
22  *  volume, ...) locking a device is done for an operation
23  *  that takes a short time such as writing data to the
24  *  device.
25  *
26  *
27  *   Kern Sibbald, MM, MMI
28  *
29  *   Version $Id$
30  */
31 /*
32    Copyright (C) 2000-2005 Kern Sibbald
33
34    This program is free software; you can redistribute it and/or
35    modify it under the terms of the GNU General Public License
36    version 2 as amended with additional clauses defined in the
37    file LICENSE in the main source directory.
38
39    This program is distributed in the hope that it will be useful,
40    but WITHOUT ANY WARRANTY; without even the implied warranty of
41    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
42    the file LICENSE for additional details.
43
44  */
45
46 #include "bacula.h"                   /* pull in global headers */
47 #include "stored.h"                   /* pull in Storage Deamon headers */
48
49 /* Forward referenced functions */
50
51 extern char my_name[];
52 extern int debug_level;
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
70  *
71  *  Returns: true  on success
72  *           false on failure
73  */
74 bool fixup_device_block_write_error(DCR *dcr)
75 {
76    char PrevVolName[MAX_NAME_LENGTH];
77    DEV_BLOCK *label_blk;
78    DEV_BLOCK *block = dcr->block;
79    char b1[30], b2[30];
80    time_t wait_time;
81    char dt[MAX_TIME_LENGTH];
82    JCR *jcr = dcr->jcr;
83    DEVICE *dev = dcr->dev;
84
85    wait_time = time(NULL);
86
87    Dmsg0(100, "Enter fixup_device_block_write_error\n");
88
89    block_device(dev, BST_DOING_ACQUIRE);
90    /* Unlock, but leave BLOCKED */
91    unlock_device(dev);
92
93    bstrncpy(PrevVolName, dev->VolCatInfo.VolCatName, sizeof(PrevVolName));
94    bstrncpy(dev->VolHdr.PrevVolumeName, PrevVolName, sizeof(dev->VolHdr.PrevVolumeName));
95
96    label_blk = new_block(dev);
97    dcr->block = label_blk;
98
99    /* Inform User about end of medium */
100    Jmsg(jcr, M_INFO, 0, _("End of medium on Volume \"%s\" Bytes=%s Blocks=%s at %s.\n"),
101         PrevVolName, edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, b1),
102         edit_uint64_with_commas(dev->VolCatInfo.VolCatBlocks, b2),
103         bstrftime(dt, sizeof(dt), time(NULL)));
104
105    if (!mount_next_write_volume(dcr, 1)) {
106       free_block(label_blk);
107       dcr->block = block;
108       P(dev->mutex);
109       unblock_device(dev);
110       return false;                /* device locked */
111    }
112    P(dev->mutex);                  /* lock again */
113
114    Jmsg(jcr, M_INFO, 0, _("New volume \"%s\" mounted on device %s at %s.\n"),
115       dcr->VolumeName, dev->print_name(), bstrftime(dt, sizeof(dt), time(NULL)));
116
117    /*
118     * If this is a new tape, the label_blk will contain the
119     *  label, so write it now. If this is a previously
120     *  used tape, mount_next_write_volume() will return an
121     *  empty label_blk, and nothing will be written.
122     */
123    Dmsg0(190, "write label block to dev\n");
124    if (!write_block_to_dev(dcr)) {
125       berrno be;
126       Pmsg1(0, _("write_block_to_device Volume label failed. ERR=%s"),
127         be.strerror(dev->dev_errno));
128       free_block(label_blk);
129       dcr->block = block;
130       unblock_device(dev);
131       return false;                /* device locked */
132    }
133    free_block(label_blk);
134    dcr->block = block;
135
136    /*
137     * Walk through all attached jcrs indicating the volume has changed
138     */
139    Dmsg1(100, "Walk attached jcrs. Volume=%s\n", dev->VolCatInfo.VolCatName);
140 // for (JCR *mjcr=NULL; (mjcr=next_attached_jcr(dev, mjcr)); ) {
141    DCR *mdcr;
142    foreach_dlist(mdcr, dev->attached_dcrs) {
143       JCR *mjcr = mdcr->jcr;
144       if (mjcr->JobId == 0) {
145          continue;                 /* ignore console */
146       }
147       mdcr->NewVol = true;
148       if (jcr != mjcr) {
149          bstrncpy(mdcr->VolumeName, dcr->VolumeName, sizeof(mdcr->VolumeName));
150       }
151    }
152
153    /* Clear NewVol now because dir_get_volume_info() already done */
154    jcr->dcr->NewVol = false;
155    set_new_volume_parameters(dcr);
156
157    jcr->run_time += time(NULL) - wait_time; /* correct run time for mount wait */
158
159    /* Write overflow block to device */
160    Dmsg0(190, "Write overflow block to dev\n");
161    if (!write_block_to_dev(dcr)) {
162       berrno be;
163       Pmsg1(0, _("write_block_to_device overflow block failed. ERR=%s"),
164         be.strerror(dev->dev_errno));
165       unblock_device(dev);
166       return false;                /* device locked */
167    }
168
169    unblock_device(dev);
170    return true;                             /* device locked */
171 }
172
173 /*
174  * We have a new Volume mounted, so reset the Volume parameters
175  *  concerning this job.  The global changes were made earlier
176  *  in the dev structure.
177  */
178 void set_new_volume_parameters(DCR *dcr)
179 {
180    JCR *jcr = dcr->jcr;
181    DEVICE *dev = dcr->dev;
182    if (dcr->NewVol && !dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE)) {
183       Jmsg1(jcr, M_ERROR, 0, "%s", jcr->errmsg);
184    }
185    /* Set new start/end positions */
186    if (dev->is_tape()) {
187       dcr->StartBlock = dev->block_num;
188       dcr->StartFile = dev->file;
189    } else {
190       dcr->StartBlock = (uint32_t)dev->file_addr;
191       dcr->StartFile  = (uint32_t)(dev->file_addr >> 32);
192    }
193    /* Reset indicies */
194    dcr->VolFirstIndex = 0;
195    dcr->VolLastIndex = 0;
196    jcr->NumVolumes++;
197    dcr->NewVol = false;
198    dcr->WroteVol = false;
199 }
200
201 /*
202  * We are now in a new Volume file, so reset the Volume parameters
203  *  concerning this job.  The global changes were made earlier
204  *  in the dev structure.
205  */
206 void set_new_file_parameters(DCR *dcr)
207 {
208    DEVICE *dev = dcr->dev;
209
210    /* Set new start/end positions */
211    if (dev->is_tape()) {
212       dcr->StartBlock = dev->block_num;
213       dcr->StartFile = dev->file;
214    } else {
215       dcr->StartBlock = (uint32_t)dev->file_addr;
216       dcr->StartFile  = (uint32_t)(dev->file_addr >> 32);
217    }
218    /* Reset indicies */
219    dcr->VolFirstIndex = 0;
220    dcr->VolLastIndex = 0;
221    dcr->NewFile = false;
222    dcr->WroteVol = false;
223 }
224
225
226
227 /*
228  *   First Open of the device. Expect dev to already be initialized.
229  *
230  *   This routine is used only when the Storage daemon starts
231  *   and always_open is set, and in the stand-alone utility
232  *   routines such as bextract.
233  *
234  *   Note, opening of a normal file is deferred to later so
235  *    that we can get the filename; the device_name for
236  *    a file is the directory only.
237  *
238  *   Returns: false on failure
239  *            true  on success
240  */
241 bool first_open_device(DCR *dcr)
242 {
243    DEVICE *dev = dcr->dev;
244    bool ok = true;
245
246    Dmsg0(120, "start open_output_device()\n");
247    if (!dev) {
248       return false;
249    }
250
251    lock_device(dev);
252
253    /* Defer opening files */
254    if (!dev->is_tape()) {
255       Dmsg0(129, "Device is file, deferring open.\n");
256       goto bail_out;
257    }
258
259     int mode;
260     if (dev_cap(dev, CAP_STREAM)) {
261        mode = OPEN_WRITE_ONLY;
262     } else {
263        mode = OPEN_READ_ONLY;
264     }
265    Dmsg0(129, "Opening device.\n");
266    dev->open_nowait = true;
267    if (dev->open(dcr, mode) < 0) {
268       Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg);
269       ok = false;
270       goto bail_out;
271    }
272    Dmsg1(129, "open dev %s OK\n", dev->print_name());
273
274 bail_out:
275    dev->open_nowait = false;
276    unlock_device(dev);
277    return ok;
278 }
279
280 /*
281  * Make sure device is open, if not do so
282  */
283 bool open_device(DCR *dcr)
284 {
285    DEVICE *dev = dcr->dev;
286    /* Open device */
287    int mode;
288    if (dev_cap(dev, CAP_STREAM)) {
289       mode = OPEN_WRITE_ONLY;
290    } else {
291       mode = OPEN_READ_WRITE;
292    }
293    if (dev->open(dcr, mode) < 0) {
294       /* If polling, ignore the error */
295       /* If DVD, also ignore the error, very often you cannot open the device
296        * (when there is no DVD, or when the one inserted is a wrong one) */
297       if ((!dev->poll) && (!dev->is_dvd())) {
298          Jmsg2(dcr->jcr, M_FATAL, 0, _("Unable to open device %s: ERR=%s\n"),
299             dev->print_name(), strerror_dev(dev));
300          Pmsg2(000, _("Unable to open archive %s: ERR=%s\n"), 
301             dev->print_name(), strerror_dev(dev));
302       }
303       return false;
304    }
305    return true;
306 }
307
308 /*
309  * Release any Volume attached to this device 
310  *  then close the device.
311  */
312 void close_device(DEVICE *dev)
313 {
314    free_volume(dev);
315    dev->close();
316 }
317
318 /*
319  * Used when unmounting the device, ignore use_count
320  */
321 void force_close_device(DEVICE *dev)
322 {
323    if (!dev || dev->fd < 0) {
324       return;
325    }
326    Dmsg1(29, "Force close_dev %s\n", dev->print_name());
327    dev->use_count = 1;
328    dev->close();
329
330 #ifdef FULL_DEBUG
331    ASSERT(dev->use_count >= 0);
332 #endif
333 }
334
335
336 void dev_lock(DEVICE *dev)
337 {
338    int errstat;
339    if ((errstat=rwl_writelock(&dev->lock))) {
340       Emsg1(M_ABORT, 0, _("Device write lock failure. ERR=%s\n"), strerror(errstat));
341    }
342 }
343
344 void dev_unlock(DEVICE *dev)
345 {
346    int errstat;
347    if ((errstat=rwl_writeunlock(&dev->lock))) {
348       Emsg1(M_ABORT, 0, _("Device write unlock failure. ERR=%s\n"), strerror(errstat));
349    }
350 }
351
352 /*
353  * When dev_blocked is set, all threads EXCEPT thread with id no_wait_id
354  * must wait. The no_wait_id thread is out obtaining a new volume
355  * and preparing the label.
356  */
357 void _lock_device(const char *file, int line, DEVICE *dev)
358 {
359    int stat;
360    Dmsg3(500, "lock %d from %s:%d\n", dev->dev_blocked, file, line);
361    P(dev->mutex);
362    if (dev->dev_blocked && !pthread_equal(dev->no_wait_id, pthread_self())) {
363       dev->num_waiting++;             /* indicate that I am waiting */
364       while (dev->dev_blocked) {
365          if ((stat = pthread_cond_wait(&dev->wait, &dev->mutex)) != 0) {
366             V(dev->mutex);
367             Emsg1(M_ABORT, 0, _("pthread_cond_wait failure. ERR=%s\n"),
368                strerror(stat));
369          }
370       }
371       dev->num_waiting--;             /* no longer waiting */
372    }
373 }
374
375 /*
376  * Check if the device is blocked or not
377  */
378 bool is_device_unmounted(DEVICE *dev)
379 {
380    bool stat;
381    int blocked = dev->dev_blocked;
382    stat = (blocked == BST_UNMOUNTED) ||
383           (blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP);
384    return stat;
385 }
386
387 void _unlock_device(const char *file, int line, DEVICE *dev)
388 {
389    Dmsg2(500, "unlock from %s:%d\n", file, line);
390    V(dev->mutex);
391 }
392
393 /*
394  * Block all other threads from using the device
395  *  Device must already be locked.  After this call,
396  *  the device is blocked to any thread calling lock_device(),
397  *  but the device is not locked (i.e. no P on device).  Also,
398  *  the current thread can do slip through the lock_device()
399  *  calls without blocking.
400  */
401 void _block_device(const char *file, int line, DEVICE *dev, int state)
402 {
403    Dmsg3(500, "block set %d from %s:%d\n", state, file, line);
404    ASSERT(dev->get_blocked() == BST_NOT_BLOCKED);
405    dev->set_blocked(state);           /* make other threads wait */
406    dev->no_wait_id = pthread_self();  /* allow us to continue */
407 }
408
409
410
411 /*
412  * Unblock the device, and wake up anyone who went to sleep.
413  */
414 void _unblock_device(const char *file, int line, DEVICE *dev)
415 {
416    Dmsg3(500, "unblock %s from %s:%d\n", dev->print_blocked(), file, line);
417    ASSERT(dev->dev_blocked);
418    dev->set_blocked(BST_NOT_BLOCKED);
419    dev->no_wait_id = 0;
420    if (dev->num_waiting > 0) {
421       pthread_cond_broadcast(&dev->wait); /* wake them up */
422    }
423 }
424
425 /*
426  * Enter with device locked and blocked
427  * Exit with device unlocked and blocked by us.
428  */
429 void _steal_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold, int state)
430 {
431
432    Dmsg3(400, "steal lock. old=%s from %s:%d\n", dev->print_blocked(),
433       file, line);
434    hold->dev_blocked = dev->get_blocked();
435    hold->dev_prev_blocked = dev->dev_prev_blocked;
436    hold->no_wait_id = dev->no_wait_id;
437    dev->set_blocked(state);
438    Dmsg1(400, "steal lock. new=%s\n", dev->print_blocked());
439    dev->no_wait_id = pthread_self();
440    V(dev->mutex);
441 }
442
443 /*
444  * Enter with device blocked by us but not locked
445  * Exit with device locked, and blocked by previous owner
446  */
447 void _give_back_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold)
448 {
449    Dmsg3(400, "return lock. old=%s from %s:%d\n",
450       dev->print_blocked(), file, line);
451    P(dev->mutex);
452    dev->dev_blocked = hold->dev_blocked;
453    dev->dev_prev_blocked = hold->dev_prev_blocked;
454    dev->no_wait_id = hold->no_wait_id;
455    Dmsg1(400, "return lock. new=%s\n", dev->print_blocked());
456    if (dev->num_waiting > 0) {
457       Dmsg0(400, "Broadcast\n");
458       pthread_cond_broadcast(&dev->wait); /* wake them up */
459    }
460 }