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 Bacula® - The Network Backup Solution
34 Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
36 The main author of Bacula is Kern Sibbald, with contributions from
37 many others, a complete list can be found in the file AUTHORS.
38 This program is Free Software; you can redistribute it and/or
39 modify it under the terms of version two of the GNU General Public
40 License as published by the Free Software Foundation plus additions
41 that are listed in the file LICENSE.
43 This program is distributed in the hope that it will be useful, but
44 WITHOUT ANY WARRANTY; without even the implied warranty of
45 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
46 General Public License for more details.
48 You should have received a copy of the GNU General Public License
49 along with this program; if not, write to the Free Software
50 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
53 Bacula® is a registered trademark of John Walker.
54 The licensor of Bacula is the Free Software Foundation Europe
55 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
56 Switzerland, email:ftf@fsfeurope.org.
59 #include "bacula.h" /* pull in global headers */
60 #include "stored.h" /* pull in Storage Deamon headers */
62 /* Forward referenced functions */
65 * This is the dreaded moment. We either have an end of
66 * medium condition or worse, and error condition.
67 * Attempt to "recover" by obtaining a new Volume.
69 * Here are a few things to know:
70 * dcr->VolCatInfo contains the info on the "current" tape for this job.
71 * dev->VolCatInfo contains the info on the tape in the drive.
72 * The tape in the drive could have changed several times since
73 * the last time the job used it (jcr->VolCatInfo).
74 * dcr->VolumeName is the name of the current/desired tape in the drive.
76 * We enter with device locked, and
77 * exit with device locked.
79 * Note, we are called only from one place in block.c for the daemons.
80 * The btape utility calls it from btape.c.
82 * Returns: true on success
85 bool fixup_device_block_write_error(DCR *dcr)
87 char PrevVolName[MAX_NAME_LENGTH];
89 DEV_BLOCK *block = dcr->block;
92 char dt[MAX_TIME_LENGTH];
94 DEVICE *dev = dcr->dev;
96 wait_time = time(NULL);
98 Dmsg0(100, "Enter fixup_device_block_write_error\n");
100 block_device(dev, BST_DOING_ACQUIRE);
101 /* Unlock, but leave BLOCKED */
104 bstrncpy(PrevVolName, dev->VolCatInfo.VolCatName, sizeof(PrevVolName));
105 bstrncpy(dev->VolHdr.PrevVolumeName, PrevVolName, sizeof(dev->VolHdr.PrevVolumeName));
107 label_blk = new_block(dev);
108 dcr->block = label_blk;
110 /* Inform User about end of medium */
111 Jmsg(jcr, M_INFO, 0, _("End of medium on Volume \"%s\" Bytes=%s Blocks=%s at %s.\n"),
112 PrevVolName, edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, b1),
113 edit_uint64_with_commas(dev->VolCatInfo.VolCatBlocks, b2),
114 bstrftime(dt, sizeof(dt), time(NULL)));
116 if (!mount_next_write_volume(dcr, 1)) {
117 free_block(label_blk);
121 return false; /* device locked */
123 P(dev->mutex); /* lock again */
125 Jmsg(jcr, M_INFO, 0, _("New volume \"%s\" mounted on device %s at %s.\n"),
126 dcr->VolumeName, dev->print_name(), bstrftime(dt, sizeof(dt), time(NULL)));
129 * If this is a new tape, the label_blk will contain the
130 * label, so write it now. If this is a previously
131 * used tape, mount_next_write_volume() will return an
132 * empty label_blk, and nothing will be written.
134 Dmsg0(190, "write label block to dev\n");
135 if (!write_block_to_dev(dcr)) {
137 Pmsg1(0, _("write_block_to_device Volume label failed. ERR=%s"),
138 be.strerror(dev->dev_errno));
139 free_block(label_blk);
142 return false; /* device locked */
144 free_block(label_blk);
148 * Walk through all attached jcrs indicating the volume has changed
150 Dmsg1(100, "Walk attached dcrs. Volume=%s\n", dev->VolCatInfo.VolCatName);
152 foreach_dlist(mdcr, dev->attached_dcrs) {
153 JCR *mjcr = mdcr->jcr;
154 if (mjcr->JobId == 0) {
155 continue; /* ignore console */
159 bstrncpy(mdcr->VolumeName, dcr->VolumeName, sizeof(mdcr->VolumeName));
163 /* Clear NewVol now because dir_get_volume_info() already done */
164 jcr->dcr->NewVol = false;
165 set_new_volume_parameters(dcr);
167 jcr->run_time += time(NULL) - wait_time; /* correct run time for mount wait */
169 /* Write overflow block to device */
170 Dmsg0(190, "Write overflow block to dev\n");
171 if (!write_block_to_dev(dcr)) {
173 Pmsg1(0, _("write_block_to_device overflow block failed. ERR=%s"),
174 be.strerror(dev->dev_errno));
176 return false; /* device locked */
180 return true; /* device locked */
184 * We have a new Volume mounted, so reset the Volume parameters
185 * concerning this job. The global changes were made earlier
186 * in the dev structure.
188 void set_new_volume_parameters(DCR *dcr)
191 DEVICE *dev = dcr->dev;
192 if (dcr->NewVol && !dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE)) {
193 Jmsg1(jcr, M_ERROR, 0, "%s", jcr->errmsg);
195 /* Set new start/end positions */
196 if (dev->is_tape()) {
197 dcr->StartBlock = dev->block_num;
198 dcr->StartFile = dev->file;
200 dcr->StartBlock = (uint32_t)dev->file_addr;
201 dcr->StartFile = (uint32_t)(dev->file_addr >> 32);
204 dcr->VolFirstIndex = 0;
205 dcr->VolLastIndex = 0;
208 dcr->WroteVol = false;
212 * We are now in a new Volume file, so reset the Volume parameters
213 * concerning this job. The global changes were made earlier
214 * in the dev structure.
216 void set_new_file_parameters(DCR *dcr)
218 DEVICE *dev = dcr->dev;
220 /* Set new start/end positions */
221 if (dev->is_tape()) {
222 dcr->StartBlock = dev->block_num;
223 dcr->StartFile = dev->file;
225 dcr->StartBlock = (uint32_t)dev->file_addr;
226 dcr->StartFile = (uint32_t)(dev->file_addr >> 32);
229 dcr->VolFirstIndex = 0;
230 dcr->VolLastIndex = 0;
231 dcr->NewFile = false;
232 dcr->WroteVol = false;
238 * First Open of the device. Expect dev to already be initialized.
240 * This routine is used only when the Storage daemon starts
241 * and always_open is set, and in the stand-alone utility
242 * routines such as bextract.
244 * Note, opening of a normal file is deferred to later so
245 * that we can get the filename; the device_name for
246 * a file is the directory only.
248 * Returns: false on failure
251 bool first_open_device(DCR *dcr)
253 DEVICE *dev = dcr->dev;
256 Dmsg0(120, "start open_output_device()\n");
263 /* Defer opening files */
264 if (!dev->is_tape()) {
265 Dmsg0(129, "Device is file, deferring open.\n");
270 if (dev_cap(dev, CAP_STREAM)) {
271 mode = OPEN_WRITE_ONLY;
273 mode = OPEN_READ_ONLY;
275 Dmsg0(129, "Opening device.\n");
276 if (dev->open(dcr, mode) < 0) {
277 Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg);
281 Dmsg1(129, "open dev %s OK\n", dev->print_name());
289 * Make sure device is open, if not do so
291 bool open_device(DCR *dcr)
293 DEVICE *dev = dcr->dev;
296 if (dev_cap(dev, CAP_STREAM)) {
297 mode = OPEN_WRITE_ONLY;
299 mode = OPEN_READ_WRITE;
301 if (dev->open(dcr, mode) < 0) {
302 /* If polling, ignore the error */
303 /* If DVD, also ignore the error, very often you cannot open the device
304 * (when there is no DVD, or when the one inserted is a wrong one) */
305 if (!dev->poll && !dev->is_dvd() && !dev->is_removable()) {
306 Jmsg2(dcr->jcr, M_FATAL, 0, _("Unable to open device %s: ERR=%s\n"),
307 dev->print_name(), dev->bstrerror());
308 Pmsg2(000, _("Unable to open archive %s: ERR=%s\n"),
309 dev->print_name(), dev->bstrerror());
318 void dev_lock(DEVICE *dev)
321 if ((errstat=rwl_writelock(&dev->lock))) {
322 Emsg1(M_ABORT, 0, _("Device write lock failure. ERR=%s\n"), strerror(errstat));
326 void dev_unlock(DEVICE *dev)
329 if ((errstat=rwl_writeunlock(&dev->lock))) {
330 Emsg1(M_ABORT, 0, _("Device write unlock failure. ERR=%s\n"), strerror(errstat));
335 * When dev_blocked is set, all threads EXCEPT thread with id no_wait_id
336 * must wait. The no_wait_id thread is out obtaining a new volume
337 * and preparing the label.
339 void _lock_device(const char *file, int line, DEVICE *dev)
342 Dmsg3(500, "lock %d from %s:%d\n", dev->dev_blocked, file, line);
344 if (dev->dev_blocked && !pthread_equal(dev->no_wait_id, pthread_self())) {
345 dev->num_waiting++; /* indicate that I am waiting */
346 while (dev->dev_blocked) {
347 if ((stat = pthread_cond_wait(&dev->wait, &dev->mutex)) != 0) {
349 Emsg1(M_ABORT, 0, _("pthread_cond_wait failure. ERR=%s\n"),
353 dev->num_waiting--; /* no longer waiting */
358 * Check if the device is blocked or not
360 bool is_device_unmounted(DEVICE *dev)
363 int blocked = dev->dev_blocked;
364 stat = (blocked == BST_UNMOUNTED) ||
365 (blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP);
369 void _unlock_device(const char *file, int line, DEVICE *dev)
371 Dmsg2(500, "unlock from %s:%d\n", file, line);
376 * Block all other threads from using the device
377 * Device must already be locked. After this call,
378 * the device is blocked to any thread calling lock_device(),
379 * but the device is not locked (i.e. no P on device). Also,
380 * the current thread can do slip through the lock_device()
381 * calls without blocking.
383 void _block_device(const char *file, int line, DEVICE *dev, int state)
385 Dmsg3(500, "block set %d from %s:%d\n", state, file, line);
386 ASSERT(dev->get_blocked() == BST_NOT_BLOCKED);
387 dev->set_blocked(state); /* make other threads wait */
388 dev->no_wait_id = pthread_self(); /* allow us to continue */
394 * Unblock the device, and wake up anyone who went to sleep.
396 void _unblock_device(const char *file, int line, DEVICE *dev)
398 Dmsg3(500, "unblock %s from %s:%d\n", dev->print_blocked(), file, line);
399 ASSERT(dev->dev_blocked);
400 dev->set_blocked(BST_NOT_BLOCKED);
402 if (dev->num_waiting > 0) {
403 pthread_cond_broadcast(&dev->wait); /* wake them up */
408 * Enter with device locked and blocked
409 * Exit with device unlocked and blocked by us.
411 void _steal_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold, int state)
414 Dmsg3(400, "steal lock. old=%s from %s:%d\n", dev->print_blocked(),
416 hold->dev_blocked = dev->get_blocked();
417 hold->dev_prev_blocked = dev->dev_prev_blocked;
418 hold->no_wait_id = dev->no_wait_id;
419 dev->set_blocked(state);
420 Dmsg1(400, "steal lock. new=%s\n", dev->print_blocked());
421 dev->no_wait_id = pthread_self();
426 * Enter with device blocked by us but not locked
427 * Exit with device locked, and blocked by previous owner
429 void _give_back_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold)
431 Dmsg3(400, "return lock. old=%s from %s:%d\n",
432 dev->print_blocked(), file, line);
434 dev->dev_blocked = hold->dev_blocked;
435 dev->dev_prev_blocked = hold->dev_prev_blocked;
436 dev->no_wait_id = hold->no_wait_id;
437 Dmsg1(400, "return lock. new=%s\n", dev->print_blocked());
438 if (dev->num_waiting > 0) {
439 pthread_cond_broadcast(&dev->wait); /* wake them up */