3 * Higher Level Device routines.
4 * Knows about Bacula tape labels and such
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.
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
27 * Kern Sibbald, MM, MMI
32 Copyright (C) 2000-2006 Kern Sibbald
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.
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.
46 #include "bacula.h" /* pull in global headers */
47 #include "stored.h" /* pull in Storage Deamon headers */
49 /* Forward referenced functions */
52 * This is the dreaded moment. We either have an end of
53 * medium condition or worse, and error condition.
54 * Attempt to "recover" by obtaining a new Volume.
56 * Here are a few things to know:
57 * dcr->VolCatInfo contains the info on the "current" tape for this job.
58 * dev->VolCatInfo contains the info on the tape in the drive.
59 * The tape in the drive could have changed several times since
60 * the last time the job used it (jcr->VolCatInfo).
61 * dcr->VolumeName is the name of the current/desired tape in the drive.
63 * We enter with device locked, and
64 * exit with device locked.
66 * Note, we are called only from one place in block.c for the daemons.
67 * The btape utility calls it from btape.c.
69 * Returns: true on success
72 bool fixup_device_block_write_error(DCR *dcr)
74 char PrevVolName[MAX_NAME_LENGTH];
76 DEV_BLOCK *block = dcr->block;
79 char dt[MAX_TIME_LENGTH];
81 DEVICE *dev = dcr->dev;
83 wait_time = time(NULL);
85 Dmsg0(100, "Enter fixup_device_block_write_error\n");
87 block_device(dev, BST_DOING_ACQUIRE);
88 /* Unlock, but leave BLOCKED */
91 bstrncpy(PrevVolName, dev->VolCatInfo.VolCatName, sizeof(PrevVolName));
92 bstrncpy(dev->VolHdr.PrevVolumeName, PrevVolName, sizeof(dev->VolHdr.PrevVolumeName));
94 label_blk = new_block(dev);
95 dcr->block = label_blk;
97 /* Inform User about end of medium */
98 Jmsg(jcr, M_INFO, 0, _("End of medium on Volume \"%s\" Bytes=%s Blocks=%s at %s.\n"),
99 PrevVolName, edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, b1),
100 edit_uint64_with_commas(dev->VolCatInfo.VolCatBlocks, b2),
101 bstrftime(dt, sizeof(dt), time(NULL)));
103 if (!mount_next_write_volume(dcr, 1)) {
104 free_block(label_blk);
108 return false; /* device locked */
110 P(dev->mutex); /* lock again */
112 Jmsg(jcr, M_INFO, 0, _("New volume \"%s\" mounted on device %s at %s.\n"),
113 dcr->VolumeName, dev->print_name(), bstrftime(dt, sizeof(dt), time(NULL)));
116 * If this is a new tape, the label_blk will contain the
117 * label, so write it now. If this is a previously
118 * used tape, mount_next_write_volume() will return an
119 * empty label_blk, and nothing will be written.
121 Dmsg0(190, "write label block to dev\n");
122 if (!write_block_to_dev(dcr)) {
124 Pmsg1(0, _("write_block_to_device Volume label failed. ERR=%s"),
125 be.strerror(dev->dev_errno));
126 free_block(label_blk);
129 return false; /* device locked */
131 free_block(label_blk);
135 * Walk through all attached jcrs indicating the volume has changed
137 Dmsg1(100, "Walk attached dcrs. Volume=%s\n", dev->VolCatInfo.VolCatName);
139 foreach_dlist(mdcr, dev->attached_dcrs) {
140 JCR *mjcr = mdcr->jcr;
141 if (mjcr->JobId == 0) {
142 continue; /* ignore console */
146 bstrncpy(mdcr->VolumeName, dcr->VolumeName, sizeof(mdcr->VolumeName));
150 /* Clear NewVol now because dir_get_volume_info() already done */
151 jcr->dcr->NewVol = false;
152 set_new_volume_parameters(dcr);
154 jcr->run_time += time(NULL) - wait_time; /* correct run time for mount wait */
156 /* Write overflow block to device */
157 Dmsg0(190, "Write overflow block to dev\n");
158 if (!write_block_to_dev(dcr)) {
160 Pmsg1(0, _("write_block_to_device overflow block failed. ERR=%s"),
161 be.strerror(dev->dev_errno));
163 return false; /* device locked */
167 return true; /* device locked */
171 * We have a new Volume mounted, so reset the Volume parameters
172 * concerning this job. The global changes were made earlier
173 * in the dev structure.
175 void set_new_volume_parameters(DCR *dcr)
178 DEVICE *dev = dcr->dev;
179 if (dcr->NewVol && !dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE)) {
180 Jmsg1(jcr, M_ERROR, 0, "%s", jcr->errmsg);
182 /* Set new start/end positions */
183 if (dev->is_tape()) {
184 dcr->StartBlock = dev->block_num;
185 dcr->StartFile = dev->file;
187 dcr->StartBlock = (uint32_t)dev->file_addr;
188 dcr->StartFile = (uint32_t)(dev->file_addr >> 32);
191 dcr->VolFirstIndex = 0;
192 dcr->VolLastIndex = 0;
195 dcr->WroteVol = false;
199 * We are now in a new Volume file, so reset the Volume parameters
200 * concerning this job. The global changes were made earlier
201 * in the dev structure.
203 void set_new_file_parameters(DCR *dcr)
205 DEVICE *dev = dcr->dev;
207 /* Set new start/end positions */
208 if (dev->is_tape()) {
209 dcr->StartBlock = dev->block_num;
210 dcr->StartFile = dev->file;
212 dcr->StartBlock = (uint32_t)dev->file_addr;
213 dcr->StartFile = (uint32_t)(dev->file_addr >> 32);
216 dcr->VolFirstIndex = 0;
217 dcr->VolLastIndex = 0;
218 dcr->NewFile = false;
219 dcr->WroteVol = false;
225 * First Open of the device. Expect dev to already be initialized.
227 * This routine is used only when the Storage daemon starts
228 * and always_open is set, and in the stand-alone utility
229 * routines such as bextract.
231 * Note, opening of a normal file is deferred to later so
232 * that we can get the filename; the device_name for
233 * a file is the directory only.
235 * Returns: false on failure
238 bool first_open_device(DCR *dcr)
240 DEVICE *dev = dcr->dev;
243 Dmsg0(120, "start open_output_device()\n");
250 /* Defer opening files */
251 if (!dev->is_tape()) {
252 Dmsg0(129, "Device is file, deferring open.\n");
257 if (dev_cap(dev, CAP_STREAM)) {
258 mode = OPEN_WRITE_ONLY;
260 mode = OPEN_READ_ONLY;
262 Dmsg0(129, "Opening device.\n");
263 if (dev->open(dcr, mode) < 0) {
264 Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg);
268 Dmsg1(129, "open dev %s OK\n", dev->print_name());
276 * Make sure device is open, if not do so
278 bool open_device(DCR *dcr)
280 DEVICE *dev = dcr->dev;
283 if (dev_cap(dev, CAP_STREAM)) {
284 mode = OPEN_WRITE_ONLY;
286 mode = OPEN_READ_WRITE;
288 if (dev->open(dcr, mode) < 0) {
289 /* If polling, ignore the error */
290 /* If DVD, also ignore the error, very often you cannot open the device
291 * (when there is no DVD, or when the one inserted is a wrong one) */
292 if (!dev->poll && !dev->is_dvd() && !dev->is_removable()) {
293 Jmsg2(dcr->jcr, M_FATAL, 0, _("Unable to open device %s: ERR=%s\n"),
294 dev->print_name(), dev->bstrerror());
295 Pmsg2(000, _("Unable to open archive %s: ERR=%s\n"),
296 dev->print_name(), dev->bstrerror());
305 void dev_lock(DEVICE *dev)
308 if ((errstat=rwl_writelock(&dev->lock))) {
309 Emsg1(M_ABORT, 0, _("Device write lock failure. ERR=%s\n"), strerror(errstat));
313 void dev_unlock(DEVICE *dev)
316 if ((errstat=rwl_writeunlock(&dev->lock))) {
317 Emsg1(M_ABORT, 0, _("Device write unlock failure. ERR=%s\n"), strerror(errstat));
322 * When dev_blocked is set, all threads EXCEPT thread with id no_wait_id
323 * must wait. The no_wait_id thread is out obtaining a new volume
324 * and preparing the label.
326 void _lock_device(const char *file, int line, DEVICE *dev)
329 Dmsg3(500, "lock %d from %s:%d\n", dev->dev_blocked, file, line);
331 if (dev->dev_blocked && !pthread_equal(dev->no_wait_id, pthread_self())) {
332 dev->num_waiting++; /* indicate that I am waiting */
333 while (dev->dev_blocked) {
334 if ((stat = pthread_cond_wait(&dev->wait, &dev->mutex)) != 0) {
336 Emsg1(M_ABORT, 0, _("pthread_cond_wait failure. ERR=%s\n"),
340 dev->num_waiting--; /* no longer waiting */
345 * Check if the device is blocked or not
347 bool is_device_unmounted(DEVICE *dev)
350 int blocked = dev->dev_blocked;
351 stat = (blocked == BST_UNMOUNTED) ||
352 (blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP);
356 void _unlock_device(const char *file, int line, DEVICE *dev)
358 Dmsg2(500, "unlock from %s:%d\n", file, line);
363 * Block all other threads from using the device
364 * Device must already be locked. After this call,
365 * the device is blocked to any thread calling lock_device(),
366 * but the device is not locked (i.e. no P on device). Also,
367 * the current thread can do slip through the lock_device()
368 * calls without blocking.
370 void _block_device(const char *file, int line, DEVICE *dev, int state)
372 Dmsg3(500, "block set %d from %s:%d\n", state, file, line);
373 ASSERT(dev->get_blocked() == BST_NOT_BLOCKED);
374 dev->set_blocked(state); /* make other threads wait */
375 dev->no_wait_id = pthread_self(); /* allow us to continue */
381 * Unblock the device, and wake up anyone who went to sleep.
383 void _unblock_device(const char *file, int line, DEVICE *dev)
385 Dmsg3(500, "unblock %s from %s:%d\n", dev->print_blocked(), file, line);
386 ASSERT(dev->dev_blocked);
387 dev->set_blocked(BST_NOT_BLOCKED);
389 if (dev->num_waiting > 0) {
390 pthread_cond_broadcast(&dev->wait); /* wake them up */
395 * Enter with device locked and blocked
396 * Exit with device unlocked and blocked by us.
398 void _steal_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold, int state)
401 Dmsg3(400, "steal lock. old=%s from %s:%d\n", dev->print_blocked(),
403 hold->dev_blocked = dev->get_blocked();
404 hold->dev_prev_blocked = dev->dev_prev_blocked;
405 hold->no_wait_id = dev->no_wait_id;
406 dev->set_blocked(state);
407 Dmsg1(400, "steal lock. new=%s\n", dev->print_blocked());
408 dev->no_wait_id = pthread_self();
413 * Enter with device blocked by us but not locked
414 * Exit with device locked, and blocked by previous owner
416 void _give_back_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold)
418 Dmsg3(400, "return lock. old=%s from %s:%d\n",
419 dev->print_blocked(), file, line);
421 dev->dev_blocked = hold->dev_blocked;
422 dev->dev_prev_blocked = hold->dev_prev_blocked;
423 dev->no_wait_id = hold->no_wait_id;
424 Dmsg1(400, "return lock. new=%s\n", dev->print_blocked());
425 if (dev->num_waiting > 0) {
426 pthread_cond_broadcast(&dev->wait); /* wake them up */