]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/stored/device.c
- Start removing #ifdef HAVE_TLS by sneaky tricks.
[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 ammended 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    uint32_t stat;
77    char PrevVolName[MAX_NAME_LENGTH];
78    DEV_BLOCK *label_blk;
79    DEV_BLOCK *block = dcr->block;
80    char b1[30], b2[30];
81    time_t wait_time;
82    char dt[MAX_TIME_LENGTH];
83    JCR *jcr = dcr->jcr;
84    DEVICE *dev = dcr->dev;
85
86    wait_time = time(NULL);
87    stat = status_dev(dev);
88    if (!(stat & BMT_EOD)) {
89       return false;                    /* this really shouldn't happen */
90    }
91
92    Dmsg0(100, "======= Got EOD ========\n");
93
94    block_device(dev, BST_DOING_ACQUIRE);
95    /* Unlock, but leave BLOCKED */
96    unlock_device(dev);
97
98    bstrncpy(PrevVolName, dev->VolCatInfo.VolCatName, sizeof(PrevVolName));
99    bstrncpy(dev->VolHdr.PrevVolName, PrevVolName, sizeof(dev->VolHdr.PrevVolName));
100
101    label_blk = new_block(dev);
102    dcr->block = label_blk;
103
104    /* Inform User about end of medium */
105    Jmsg(jcr, M_INFO, 0, _("End of medium on Volume \"%s\" Bytes=%s Blocks=%s at %s.\n"),
106         PrevVolName, edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, b1),
107         edit_uint64_with_commas(dev->VolCatInfo.VolCatBlocks, b2),
108         bstrftime(dt, sizeof(dt), time(NULL)));
109
110    if (!mount_next_write_volume(dcr, 1)) {
111       free_block(label_blk);
112       dcr->block = block;
113       P(dev->mutex);
114       unblock_device(dev);
115       return false;                /* device locked */
116    }
117    P(dev->mutex);                  /* lock again */
118
119    Jmsg(jcr, M_INFO, 0, _("New volume \"%s\" mounted on device %s at %s.\n"),
120       dcr->VolumeName, dev->print_name(), bstrftime(dt, sizeof(dt), time(NULL)));
121
122    /*
123     * If this is a new tape, the label_blk will contain the
124     *  label, so write it now. If this is a previously
125     *  used tape, mount_next_write_volume() will return an
126     *  empty label_blk, and nothing will be written.
127     */
128    Dmsg0(190, "write label block to dev\n");
129    if (!write_block_to_dev(dcr)) {
130       berrno be;
131       Pmsg1(0, "write_block_to_device Volume label failed. ERR=%s",
132         be.strerror(dev->dev_errno));
133       free_block(label_blk);
134       dcr->block = block;
135       unblock_device(dev);
136       return false;                /* device locked */
137    }
138    free_block(label_blk);
139    dcr->block = block;
140
141    /*
142     * Walk through all attached jcrs indicating the volume has changed
143     */
144    Dmsg1(100, "Walk attached jcrs. Volume=%s\n", dev->VolCatInfo.VolCatName);
145 // for (JCR *mjcr=NULL; (mjcr=next_attached_jcr(dev, mjcr)); ) {
146    DCR *mdcr;
147    foreach_dlist(mdcr, dev->attached_dcrs) {
148       JCR *mjcr = mdcr->jcr;
149       if (mjcr->JobId == 0) {
150          continue;                 /* ignore console */
151       }
152       mdcr->NewVol = true;
153       if (jcr != mjcr) {
154          bstrncpy(mdcr->VolumeName, dcr->VolumeName, sizeof(mdcr->VolumeName));
155       }
156    }
157
158    /* Clear NewVol now because dir_get_volume_info() already done */
159    jcr->dcr->NewVol = false;
160    set_new_volume_parameters(dcr);
161
162    jcr->run_time += time(NULL) - wait_time; /* correct run time for mount wait */
163
164    /* Write overflow block to device */
165    Dmsg0(190, "Write overflow block to dev\n");
166    if (!write_block_to_dev(dcr)) {
167       berrno be;
168       Pmsg1(0, "write_block_to_device overflow block failed. ERR=%s",
169         be.strerror(dev->dev_errno));
170       unblock_device(dev);
171       return false;                /* device locked */
172    }
173
174    unblock_device(dev);
175    return true;                             /* device locked */
176 }
177
178 /*
179  * We have a new Volume mounted, so reset the Volume parameters
180  *  concerning this job.  The global changes were made earlier
181  *  in the dev structure.
182  */
183 void set_new_volume_parameters(DCR *dcr)
184 {
185    JCR *jcr = dcr->jcr;
186    DEVICE *dev = dcr->dev;
187    if (dcr->NewVol && !dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE)) {
188       Jmsg1(jcr, M_ERROR, 0, "%s", jcr->errmsg);
189    }
190    /* Set new start/end positions */
191    if (dev_state(dev, ST_TAPE)) {
192       dcr->StartBlock = dev->block_num;
193       dcr->StartFile = dev->file;
194    } else {
195       dcr->StartBlock = (uint32_t)dev->file_addr;
196       dcr->StartFile  = (uint32_t)(dev->file_addr >> 32);
197    }
198    /* Reset indicies */
199    dcr->VolFirstIndex = 0;
200    dcr->VolLastIndex = 0;
201    jcr->NumVolumes++;
202    dcr->NewVol = false;
203    dcr->WroteVol = false;
204 }
205
206 /*
207  * We are now in a new Volume file, so reset the Volume parameters
208  *  concerning this job.  The global changes were made earlier
209  *  in the dev structure.
210  */
211 void set_new_file_parameters(DCR *dcr)
212 {
213    DEVICE *dev = dcr->dev;
214
215    /* Set new start/end positions */
216    if (dev_state(dev, ST_TAPE)) {
217       dcr->StartBlock = dev->block_num;
218       dcr->StartFile = dev->file;
219    } else {
220       dcr->StartBlock = (uint32_t)dev->file_addr;
221       dcr->StartFile  = (uint32_t)(dev->file_addr >> 32);
222    }
223    /* Reset indicies */
224    dcr->VolFirstIndex = 0;
225    dcr->VolLastIndex = 0;
226    dcr->NewFile = false;
227    dcr->WroteVol = false;
228 }
229
230
231
232 /*
233  *   First Open of the device. Expect dev to already be initialized.
234  *
235  *   This routine is used only when the Storage daemon starts
236  *   and always_open is set, and in the stand-alone utility
237  *   routines such as bextract.
238  *
239  *   Note, opening of a normal file is deferred to later so
240  *    that we can get the filename; the device_name for
241  *    a file is the directory only.
242  *
243  *   Returns: false on failure
244  *            true  on success
245  */
246 bool first_open_device(DEVICE *dev)
247 {
248    Dmsg0(120, "start open_output_device()\n");
249    if (!dev) {
250       return false;
251    }
252
253    lock_device(dev);
254
255    /* Defer opening files */
256    if (!dev->is_tape()) {
257       Dmsg0(129, "Device is file, deferring open.\n");
258       unlock_device(dev);
259       return true;
260    }
261
262     int mode;
263     if (dev_cap(dev, CAP_STREAM)) {
264        mode = OPEN_WRITE_ONLY;
265     } else {
266        mode = OPEN_READ_WRITE;
267     }
268    Dmsg0(129, "Opening device.\n");
269    dev->open_nowait = true;
270    if (open_dev(dev, NULL, mode) < 0) {
271       Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg);
272       dev->open_nowait = false;
273       unlock_device(dev);
274       return false;
275    }
276    Dmsg1(129, "open_dev %s OK\n", dev->print_name());
277    dev->open_nowait = false;
278    unlock_device(dev);
279    return true;
280 }
281
282 /*
283  * Make sure device is open, if not do so
284  */
285 bool open_device(DCR *dcr)
286 {
287    DEVICE *dev = dcr->dev;
288    /* Open device */
289    int mode;
290    if (dev_cap(dev, CAP_STREAM)) {
291       mode = OPEN_WRITE_ONLY;
292    } else {
293       mode = OPEN_READ_WRITE;
294    }
295    if (open_dev(dev, dcr->VolCatInfo.VolCatName, mode) < 0) {
296       /* If polling, ignore the error */
297       if (!dev->poll) {
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) {
324       Mmsg0(dev->errmsg, _("Bad call to force_close_dev. Device not open\n"));
325       Emsg0(M_FATAL, 0, dev->errmsg);
326       return;
327    }
328    Dmsg1(29, "Force close_dev %s\n", dev->print_name());
329    dev->use_count = 1;
330    dev->close();
331
332 #ifdef FULL_DEBUG
333    ASSERT(dev->use_count >= 0);
334 #endif
335 }
336
337
338 void dev_lock(DEVICE *dev)
339 {
340    int errstat;
341    if ((errstat=rwl_writelock(&dev->lock))) {
342       Emsg1(M_ABORT, 0, "Device write lock failure. ERR=%s\n", strerror(errstat));
343    }
344 }
345
346 void dev_unlock(DEVICE *dev)
347 {
348    int errstat;
349    if ((errstat=rwl_writeunlock(&dev->lock))) {
350       Emsg1(M_ABORT, 0, "Device write unlock failure. ERR=%s\n", strerror(errstat));
351    }
352 }
353
354 /*
355  * When dev_blocked is set, all threads EXCEPT thread with id no_wait_id
356  * must wait. The no_wait_id thread is out obtaining a new volume
357  * and preparing the label.
358  */
359 void _lock_device(const char *file, int line, DEVICE *dev)
360 {
361    int stat;
362    Dmsg3(500, "lock %d from %s:%d\n", dev->dev_blocked, file, line);
363    P(dev->mutex);
364    if (dev->dev_blocked && !pthread_equal(dev->no_wait_id, pthread_self())) {
365       dev->num_waiting++;             /* indicate that I am waiting */
366       while (dev->dev_blocked) {
367          if ((stat = pthread_cond_wait(&dev->wait, &dev->mutex)) != 0) {
368             V(dev->mutex);
369             Emsg1(M_ABORT, 0, _("pthread_cond_wait failure. ERR=%s\n"),
370                strerror(stat));
371          }
372       }
373       dev->num_waiting--;             /* no longer waiting */
374    }
375 }
376
377 /*
378  * Check if the device is blocked or not
379  */
380 bool device_is_unmounted(DEVICE *dev)
381 {
382    bool stat;
383    int blocked = dev->dev_blocked;
384    stat = (blocked == BST_UNMOUNTED) ||
385           (blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP);
386    return stat;
387 }
388
389 const char *edit_blocked_reason(DEVICE *dev)
390 {
391    switch (dev->dev_blocked) {
392    case BST_NOT_BLOCKED:
393       return "not blocked";
394    case BST_UNMOUNTED:
395       return "user unmounted device";
396    case BST_WAITING_FOR_SYSOP:
397       return "waiting for operator action";
398    case BST_DOING_ACQUIRE:
399       return "opening, validating, or positioning tape";
400    case BST_WRITING_LABEL:
401       return "labeling tape";
402    case BST_UNMOUNTED_WAITING_FOR_SYSOP:
403       return "closed by user during mount request";
404    case BST_MOUNT:
405       return "mount request";
406    default:
407       return "unknown blocked code";
408    }
409 }
410
411 void _unlock_device(const char *file, int line, DEVICE *dev)
412 {
413    Dmsg2(500, "unlock from %s:%d\n", file, line);
414    V(dev->mutex);
415 }
416
417 /*
418  * Block all other threads from using the device
419  *  Device must already be locked.  After this call,
420  *  the device is blocked to any thread calling lock_device(),
421  *  but the device is not locked (i.e. no P on device).  Also,
422  *  the current thread can do slip through the lock_device()
423  *  calls without blocking.
424  */
425 void _block_device(const char *file, int line, DEVICE *dev, int state)
426 {
427    Dmsg3(500, "block set %d from %s:%d\n", state, file, line);
428    ASSERT(dev->dev_blocked == BST_NOT_BLOCKED);
429    dev->dev_blocked = state;          /* make other threads wait */
430    dev->no_wait_id = pthread_self();  /* allow us to continue */
431 }
432
433
434
435 /*
436  * Unblock the device, and wake up anyone who went to sleep.
437  */
438 void _unblock_device(const char *file, int line, DEVICE *dev)
439 {
440    Dmsg3(500, "unblock %d from %s:%d\n", dev->dev_blocked, file, line);
441    ASSERT(dev->dev_blocked);
442    dev->dev_blocked = BST_NOT_BLOCKED;
443    dev->no_wait_id = 0;
444    if (dev->num_waiting > 0) {
445       pthread_cond_broadcast(&dev->wait); /* wake them up */
446    }
447 }
448
449 /*
450  * Enter with device locked and blocked
451  * Exit with device unlocked and blocked by us.
452  */
453 void _steal_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold, int state)
454 {
455    Dmsg4(500, "steal lock. old=%d new=%d from %s:%d\n", dev->dev_blocked, state,
456       file, line);
457    hold->dev_blocked = dev->dev_blocked;
458    hold->dev_prev_blocked = dev->dev_prev_blocked;
459    hold->no_wait_id = dev->no_wait_id;
460    dev->dev_blocked = state;
461    dev->no_wait_id = pthread_self();
462    V(dev->mutex);
463 }
464
465 /*
466  * Enter with device blocked by us but not locked
467  * Exit with device locked, and blocked by previous owner
468  */
469 void _give_back_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold)
470 {
471    Dmsg4(500, "return lock. old=%d new=%d from %s:%d\n",
472       dev->dev_blocked, hold->dev_blocked, file, line);
473    P(dev->mutex);
474    dev->dev_blocked = hold->dev_blocked;
475    dev->dev_prev_blocked = hold->dev_prev_blocked;
476    dev->no_wait_id = hold->no_wait_id;
477    if (dev->dev_blocked == BST_NOT_BLOCKED && dev->num_waiting > 0) {
478       pthread_cond_broadcast(&dev->wait); /* wake them up */
479    }
480 }