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-2005 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 */
51 extern char my_name[];
52 extern int debug_level;
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.
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.
66 * We enter with device locked, and
67 * exit with device locked.
69 * Note, we are called only from one place in block.c
71 * Returns: true on success
74 bool fixup_device_block_write_error(DCR *dcr)
76 char PrevVolName[MAX_NAME_LENGTH];
78 DEV_BLOCK *block = dcr->block;
81 char dt[MAX_TIME_LENGTH];
83 DEVICE *dev = dcr->dev;
85 wait_time = time(NULL);
87 Dmsg0(100, "Enter fixup_device_block_write_error\n");
89 block_device(dev, BST_DOING_ACQUIRE);
90 /* Unlock, but leave BLOCKED */
93 bstrncpy(PrevVolName, dev->VolCatInfo.VolCatName, sizeof(PrevVolName));
94 bstrncpy(dev->VolHdr.PrevVolumeName, PrevVolName, sizeof(dev->VolHdr.PrevVolumeName));
96 label_blk = new_block(dev);
97 dcr->block = label_blk;
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)));
105 if (!mount_next_write_volume(dcr, 1)) {
106 free_block(label_blk);
110 return false; /* device locked */
112 P(dev->mutex); /* lock again */
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)));
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.
123 Dmsg0(190, "write label block to dev\n");
124 if (!write_block_to_dev(dcr)) {
126 Pmsg1(0, _("write_block_to_device Volume label failed. ERR=%s"),
127 be.strerror(dev->dev_errno));
128 free_block(label_blk);
131 return false; /* device locked */
133 free_block(label_blk);
137 * Walk through all attached jcrs indicating the volume has changed
139 Dmsg1(100, "Walk attached jcrs. Volume=%s\n", dev->VolCatInfo.VolCatName);
140 // for (JCR *mjcr=NULL; (mjcr=next_attached_jcr(dev, mjcr)); ) {
142 foreach_dlist(mdcr, dev->attached_dcrs) {
143 JCR *mjcr = mdcr->jcr;
144 if (mjcr->JobId == 0) {
145 continue; /* ignore console */
149 bstrncpy(mdcr->VolumeName, dcr->VolumeName, sizeof(mdcr->VolumeName));
153 /* Clear NewVol now because dir_get_volume_info() already done */
154 jcr->dcr->NewVol = false;
155 set_new_volume_parameters(dcr);
157 jcr->run_time += time(NULL) - wait_time; /* correct run time for mount wait */
159 /* Write overflow block to device */
160 Dmsg0(190, "Write overflow block to dev\n");
161 if (!write_block_to_dev(dcr)) {
163 Pmsg1(0, _("write_block_to_device overflow block failed. ERR=%s"),
164 be.strerror(dev->dev_errno));
166 return false; /* device locked */
170 return true; /* device locked */
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.
178 void set_new_volume_parameters(DCR *dcr)
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);
185 /* Set new start/end positions */
186 if (dev->is_tape()) {
187 dcr->StartBlock = dev->block_num;
188 dcr->StartFile = dev->file;
190 dcr->StartBlock = (uint32_t)dev->file_addr;
191 dcr->StartFile = (uint32_t)(dev->file_addr >> 32);
194 dcr->VolFirstIndex = 0;
195 dcr->VolLastIndex = 0;
198 dcr->WroteVol = false;
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.
206 void set_new_file_parameters(DCR *dcr)
208 DEVICE *dev = dcr->dev;
210 /* Set new start/end positions */
211 if (dev->is_tape()) {
212 dcr->StartBlock = dev->block_num;
213 dcr->StartFile = dev->file;
215 dcr->StartBlock = (uint32_t)dev->file_addr;
216 dcr->StartFile = (uint32_t)(dev->file_addr >> 32);
219 dcr->VolFirstIndex = 0;
220 dcr->VolLastIndex = 0;
221 dcr->NewFile = false;
222 dcr->WroteVol = false;
228 * First Open of the device. Expect dev to already be initialized.
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.
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.
238 * Returns: false on failure
241 bool first_open_device(DCR *dcr)
243 DEVICE *dev = dcr->dev;
246 Dmsg0(120, "start open_output_device()\n");
253 /* Defer opening files */
254 if (!dev->is_tape()) {
255 Dmsg0(129, "Device is file, deferring open.\n");
260 if (dev_cap(dev, CAP_STREAM)) {
261 mode = OPEN_WRITE_ONLY;
263 mode = OPEN_READ_ONLY;
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);
272 Dmsg1(129, "open dev %s OK\n", dev->print_name());
275 dev->open_nowait = false;
281 * Make sure device is open, if not do so
283 bool open_device(DCR *dcr)
285 DEVICE *dev = dcr->dev;
288 if (dev_cap(dev, CAP_STREAM)) {
289 mode = OPEN_WRITE_ONLY;
291 mode = OPEN_READ_WRITE;
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));
309 * Release any Volume attached to this device
310 * then close the device.
312 void close_device(DEVICE *dev)
319 * Used when unmounting the device, ignore use_count
321 void force_close_device(DEVICE *dev)
323 if (!dev || dev->fd < 0) {
326 Dmsg1(29, "Force close_dev %s\n", dev->print_name());
331 ASSERT(dev->use_count >= 0);
336 void dev_lock(DEVICE *dev)
339 if ((errstat=rwl_writelock(&dev->lock))) {
340 Emsg1(M_ABORT, 0, _("Device write lock failure. ERR=%s\n"), strerror(errstat));
344 void dev_unlock(DEVICE *dev)
347 if ((errstat=rwl_writeunlock(&dev->lock))) {
348 Emsg1(M_ABORT, 0, _("Device write unlock failure. ERR=%s\n"), strerror(errstat));
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.
357 void _lock_device(const char *file, int line, DEVICE *dev)
360 Dmsg3(500, "lock %d from %s:%d\n", dev->dev_blocked, file, line);
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) {
367 Emsg1(M_ABORT, 0, _("pthread_cond_wait failure. ERR=%s\n"),
371 dev->num_waiting--; /* no longer waiting */
376 * Check if the device is blocked or not
378 bool is_device_unmounted(DEVICE *dev)
381 int blocked = dev->dev_blocked;
382 stat = (blocked == BST_UNMOUNTED) ||
383 (blocked == BST_UNMOUNTED_WAITING_FOR_SYSOP);
387 void _unlock_device(const char *file, int line, DEVICE *dev)
389 Dmsg2(500, "unlock from %s:%d\n", file, line);
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.
401 void _block_device(const char *file, int line, DEVICE *dev, int state)
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 */
412 * Unblock the device, and wake up anyone who went to sleep.
414 void _unblock_device(const char *file, int line, DEVICE *dev)
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);
420 if (dev->num_waiting > 0) {
421 pthread_cond_broadcast(&dev->wait); /* wake them up */
426 * Enter with device locked and blocked
427 * Exit with device unlocked and blocked by us.
429 void _steal_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold, int state)
432 Dmsg3(400, "steal lock. old=%s from %s:%d\n", dev->print_blocked(),
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();
444 * Enter with device blocked by us but not locked
445 * Exit with device locked, and blocked by previous owner
447 void _give_back_device_lock(const char *file, int line, DEVICE *dev, bsteal_lock_t *hold)
449 Dmsg3(400, "return lock. old=%s from %s:%d\n",
450 dev->print_blocked(), file, line);
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 */