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
68 * Returns: true on success
71 bool fixup_device_block_write_error(DCR *dcr)
73 char PrevVolName[MAX_NAME_LENGTH];
75 DEV_BLOCK *block = dcr->block;
78 char dt[MAX_TIME_LENGTH];
80 DEVICE *dev = dcr->dev;
82 wait_time = time(NULL);
84 Dmsg0(100, "Enter fixup_device_block_write_error\n");
86 block_device(dev, BST_DOING_ACQUIRE);
87 /* Unlock, but leave BLOCKED */
90 bstrncpy(PrevVolName, dev->VolCatInfo.VolCatName, sizeof(PrevVolName));
91 bstrncpy(dev->VolHdr.PrevVolumeName, PrevVolName, sizeof(dev->VolHdr.PrevVolumeName));
93 label_blk = new_block(dev);
94 dcr->block = label_blk;
96 /* Inform User about end of medium */
97 Jmsg(jcr, M_INFO, 0, _("End of medium on Volume \"%s\" Bytes=%s Blocks=%s at %s.\n"),
98 PrevVolName, edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, b1),
99 edit_uint64_with_commas(dev->VolCatInfo.VolCatBlocks, b2),
100 bstrftime(dt, sizeof(dt), time(NULL)));
102 if (!mount_next_write_volume(dcr, 1)) {
103 free_block(label_blk);
107 return false; /* device locked */
109 P(dev->mutex); /* lock again */
111 Jmsg(jcr, M_INFO, 0, _("New volume \"%s\" mounted on device %s at %s.\n"),
112 dcr->VolumeName, dev->print_name(), bstrftime(dt, sizeof(dt), time(NULL)));
115 * If this is a new tape, the label_blk will contain the
116 * label, so write it now. If this is a previously
117 * used tape, mount_next_write_volume() will return an
118 * empty label_blk, and nothing will be written.
120 Dmsg0(190, "write label block to dev\n");
121 if (!write_block_to_dev(dcr)) {
123 Pmsg1(0, _("write_block_to_device Volume label failed. ERR=%s"),
124 be.strerror(dev->dev_errno));
125 free_block(label_blk);
128 return false; /* device locked */
130 free_block(label_blk);
134 * Walk through all attached jcrs indicating the volume has changed
136 Dmsg1(100, "Walk attached dcrs. Volume=%s\n", dev->VolCatInfo.VolCatName);
138 foreach_dlist(mdcr, dev->attached_dcrs) {
139 JCR *mjcr = mdcr->jcr;
140 if (mjcr->JobId == 0) {
141 continue; /* ignore console */
145 bstrncpy(mdcr->VolumeName, dcr->VolumeName, sizeof(mdcr->VolumeName));
149 /* Clear NewVol now because dir_get_volume_info() already done */
150 jcr->dcr->NewVol = false;
151 set_new_volume_parameters(dcr);
153 jcr->run_time += time(NULL) - wait_time; /* correct run time for mount wait */
155 /* Write overflow block to device */
156 Dmsg0(190, "Write overflow block to dev\n");
157 if (!write_block_to_dev(dcr)) {
159 Pmsg1(0, _("write_block_to_device overflow block failed. ERR=%s"),
160 be.strerror(dev->dev_errno));
162 return false; /* device locked */
166 return true; /* device locked */
170 * We have a new Volume mounted, so reset the Volume parameters
171 * concerning this job. The global changes were made earlier
172 * in the dev structure.
174 void set_new_volume_parameters(DCR *dcr)
177 DEVICE *dev = dcr->dev;
178 if (dcr->NewVol && !dir_get_volume_info(dcr, GET_VOL_INFO_FOR_WRITE)) {
179 Jmsg1(jcr, M_ERROR, 0, "%s", jcr->errmsg);
181 /* Set new start/end positions */
182 if (dev->is_tape()) {
183 dcr->StartBlock = dev->block_num;
184 dcr->StartFile = dev->file;
186 dcr->StartBlock = (uint32_t)dev->file_addr;
187 dcr->StartFile = (uint32_t)(dev->file_addr >> 32);
190 dcr->VolFirstIndex = 0;
191 dcr->VolLastIndex = 0;
194 dcr->WroteVol = false;
198 * We are now in a new Volume file, so reset the Volume parameters
199 * concerning this job. The global changes were made earlier
200 * in the dev structure.
202 void set_new_file_parameters(DCR *dcr)
204 DEVICE *dev = dcr->dev;
206 /* Set new start/end positions */
207 if (dev->is_tape()) {
208 dcr->StartBlock = dev->block_num;
209 dcr->StartFile = dev->file;
211 dcr->StartBlock = (uint32_t)dev->file_addr;
212 dcr->StartFile = (uint32_t)(dev->file_addr >> 32);
215 dcr->VolFirstIndex = 0;
216 dcr->VolLastIndex = 0;
217 dcr->NewFile = false;
218 dcr->WroteVol = false;
224 * First Open of the device. Expect dev to already be initialized.
226 * This routine is used only when the Storage daemon starts
227 * and always_open is set, and in the stand-alone utility
228 * routines such as bextract.
230 * Note, opening of a normal file is deferred to later so
231 * that we can get the filename; the device_name for
232 * a file is the directory only.
234 * Returns: false on failure
237 bool first_open_device(DCR *dcr)
239 DEVICE *dev = dcr->dev;
242 Dmsg0(120, "start open_output_device()\n");
249 /* Defer opening files */
250 if (!dev->is_tape()) {
251 Dmsg0(129, "Device is file, deferring open.\n");
256 if (dev_cap(dev, CAP_STREAM)) {
257 mode = OPEN_WRITE_ONLY;
259 mode = OPEN_READ_ONLY;
261 Dmsg0(129, "Opening device.\n");
262 if (dev->open(dcr, mode) < 0) {
263 Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg);
267 Dmsg1(129, "open dev %s OK\n", dev->print_name());
275 * Make sure device is open, if not do so
277 bool open_device(DCR *dcr)
279 DEVICE *dev = dcr->dev;
282 if (dev_cap(dev, CAP_STREAM)) {
283 mode = OPEN_WRITE_ONLY;
285 mode = OPEN_READ_WRITE;
287 if (dev->open(dcr, mode) < 0) {
288 /* If polling, ignore the error */
289 /* If DVD, also ignore the error, very often you cannot open the device
290 * (when there is no DVD, or when the one inserted is a wrong one) */
291 if (!dev->poll && !dev->is_dvd() && !dev->is_removable()) {
292 Jmsg2(dcr->jcr, M_FATAL, 0, _("Unable to open device %s: ERR=%s\n"),
293 dev->print_name(), dev->bstrerror());
294 Pmsg2(000, _("Unable to open archive %s: ERR=%s\n"),
295 dev->print_name(), dev->bstrerror());
304 void dev_lock(DEVICE *dev)
307 if ((errstat=rwl_writelock(&dev->lock))) {
308 Emsg1(M_ABORT, 0, _("Device write lock failure. ERR=%s\n"), strerror(errstat));
312 void dev_unlock(DEVICE *dev)
315 if ((errstat=rwl_writeunlock(&dev->lock))) {
316 Emsg1(M_ABORT, 0, _("Device write unlock failure. ERR=%s\n"), strerror(errstat));
321 * When dev_blocked is set, all threads EXCEPT thread with id no_wait_id
322 * must wait. The no_wait_id thread is out obtaining a new volume
323 * and preparing the label.
325 void _lock_device(const char *file, int line, DEVICE *dev)
328 Dmsg3(500, "lock %d from %s:%d\n", dev->dev_blocked, file, line);
330 if (dev->dev_blocked && !pthread_equal(dev->no_wait_id, pthread_self())) {
331 dev->num_waiting++; /* indicate that I am waiting */
332 while (dev->dev_blocked) {
333 if ((stat = pthread_cond_wait(&dev->wait, &dev->mutex)) != 0) {
335 Emsg1(M_ABORT, 0, _("pthread_cond_wait failure. ERR=%s\n"),
339 dev->num_waiting--; /* no longer waiting */
344 * Check if the device is blocked or not
346 bool is_device_unmounted(DEVICE *dev)
349 int blocked = dev->dev_blocked;
350 stat = (blocked == BST_UNMOUNTED) ||
351 (blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP);
355 void _unlock_device(const char *file, int line, DEVICE *dev)
357 Dmsg2(500, "unlock from %s:%d\n", file, line);
362 * Block all other threads from using the device
363 * Device must already be locked. After this call,
364 * the device is blocked to any thread calling lock_device(),
365 * but the device is not locked (i.e. no P on device). Also,
366 * the current thread can do slip through the lock_device()
367 * calls without blocking.
369 void _block_device(const char *file, int line, DEVICE *dev, int state)
371 Dmsg3(500, "block set %d from %s:%d\n", state, file, line);
372 ASSERT(dev->get_blocked() == BST_NOT_BLOCKED);
373 dev->set_blocked(state); /* make other threads wait */
374 dev->no_wait_id = pthread_self(); /* allow us to continue */
380 * Unblock the device, and wake up anyone who went to sleep.
382 void _unblock_device(const char *file, int line, DEVICE *dev)
384 Dmsg3(500, "unblock %s from %s:%d\n", dev->print_blocked(), file, line);
385 ASSERT(dev->dev_blocked);
386 dev->set_blocked(BST_NOT_BLOCKED);
388 if (dev->num_waiting > 0) {
389 pthread_cond_broadcast(&dev->wait); /* wake them up */
394 * Enter with device locked and blocked
395 * Exit with device unlocked and blocked by us.
397 void _steal_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold, int state)
400 Dmsg3(400, "steal lock. old=%s from %s:%d\n", dev->print_blocked(),
402 hold->dev_blocked = dev->get_blocked();
403 hold->dev_prev_blocked = dev->dev_prev_blocked;
404 hold->no_wait_id = dev->no_wait_id;
405 dev->set_blocked(state);
406 Dmsg1(400, "steal lock. new=%s\n", dev->print_blocked());
407 dev->no_wait_id = pthread_self();
412 * Enter with device blocked by us but not locked
413 * Exit with device locked, and blocked by previous owner
415 void _give_back_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold)
417 Dmsg3(400, "return lock. old=%s from %s:%d\n",
418 dev->print_blocked(), file, line);
420 dev->dev_blocked = hold->dev_blocked;
421 dev->dev_prev_blocked = hold->dev_prev_blocked;
422 dev->no_wait_id = hold->no_wait_id;
423 Dmsg1(400, "return lock. new=%s\n", dev->print_blocked());
424 if (dev->num_waiting > 0) {
425 pthread_cond_broadcast(&dev->wait); /* wake them up */