2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2016 Kern Sibbald
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many others, a complete list can be found in the file AUTHORS.
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
17 Bacula(R) is a registered trademark of Kern Sibbald.
21 * dev.c -- low level operations on device (storage device)
23 * written by, Kern Sibbald, MM
25 * NOTE!!!! None of these routines are reentrant. You must
26 * use dev->rLock() and dev->Unlock() at a higher level,
27 * or use the xxx_device() equivalents. By moving the
28 * thread synchronization to a higher level, we permit
29 * the higher level routines to "seize" the device and
30 * to carry out operations without worrying about who
31 * set what lock (i.e. race conditions).
33 * Note, this is the device dependent code, and may have
34 * to be modified for each system, but is meant to
35 * be as "generic" as possible.
37 * The purpose of this code is to develop a SIMPLE Storage
38 * daemon. More complicated coding (double buffering, writer
39 * thread, ...) is left for a later version.
44 * Handling I/O errors and end of tape conditions are a bit tricky.
45 * This is how it is currently done when writing.
46 * On either an I/O error or end of tape,
47 * we will stop writing on the physical device (no I/O recovery is
48 * attempted at least in this daemon). The state flag will be sent
49 * to include ST_EOT, which is ephemeral, and ST_WEOT, which is
50 * persistent. Lots of routines clear ST_EOT, but ST_WEOT is
51 * cleared only when the problem goes away. Now when ST_WEOT
52 * is set all calls to write_block_to_device() call the fix_up
53 * routine. In addition, all threads are blocked
54 * from writing on the tape by calling lock_dev(), and thread other
55 * than the first thread to hit the EOT will block on a condition
56 * variable. The first thread to hit the EOT will continue to
57 * be able to read and write the tape (he sort of tunnels through
58 * the locking mechanism -- see lock_dev() for details).
60 * Now presumably somewhere higher in the chain of command
61 * (device.c), someone will notice the EOT condition and
62 * get a new tape up, get the tape label read, and mark
63 * the label for rewriting. Then this higher level routine
64 * will write the unwritten buffer to the new volume.
65 * Finally, he will release
66 * any blocked threads by doing a broadcast on the condition
67 * variable. At that point, we should be totally back in
68 * business with no lost data.
78 /* Imported functions */
79 extern void set_os_device_parameters(DCR *dcr);
80 extern bool dev_get_os_pos(DEVICE *dev, struct mtget *mt_stat);
81 extern uint32_t status_dev(DEVICE *dev);
83 /* Forward referenced functions */
84 const char *mode_to_str(int mode);
85 DEVICE *m_init_dev(JCR *jcr, DEVRES *device);
87 * Device types for printing
89 static const char *prt_dev_types[] = {
101 * Allocate and initialize the DEVICE structure
102 * Note, if dev is non-NULL, it is already allocated,
103 * thus we neither allocate it nor free it. This allows
104 * the caller to put the packet in shared memory.
106 * Note, for a tape, the device->device_name is the device name
107 * (e.g. /dev/nst0), and for a file, the device name
108 * is the directory in which the file will be placed.
111 DEVICE *init_dev(JCR *jcr, DEVRES *device)
113 generate_global_plugin_event(bsdGlobalEventDeviceInit, device);
114 DEVICE *dev = m_init_dev(jcr, device);
118 DEVICE *m_init_dev(JCR *jcr, DEVRES *device)
126 /* If no device type specified, try to guess */
127 if (!device->dev_type) {
128 /* Check that device is available */
129 if (stat(device->device_name, &statp) < 0) {
131 Jmsg2(jcr, M_ERROR, 0, _("Unable to stat device %s: ERR=%s\n"),
132 device->device_name, be.bstrerror());
135 if (S_ISDIR(statp.st_mode)) {
136 device->dev_type = B_FILE_DEV;
137 } else if (S_ISCHR(statp.st_mode)) {
138 device->dev_type = B_TAPE_DEV;
139 } else if (S_ISFIFO(statp.st_mode)) {
140 device->dev_type = B_FIFO_DEV;
142 /* must set DeviceType = Vtape
143 * in normal mode, autodetection is disabled
145 } else if (S_ISREG(statp.st_mode)) {
146 device->dev_type = B_VTAPE_DEV;
148 } else if (!(device->cap_bits & CAP_REQMOUNT)) {
149 Jmsg2(jcr, M_ERROR, 0, _("%s is an unknown device type. Must be tape or directory\n"
150 " or have RequiresMount=yes for DVD. st_mode=%x\n"),
151 device->device_name, statp.st_mode);
154 device->dev_type = B_DVD_DEV;
156 if (strcmp(device->device_name, "/dev/null") == 0) {
157 device->dev_type = B_NULL_DEV;
160 switch (device->dev_type) {
162 Jmsg0(jcr, M_FATAL, 0, _("DVD support is now deprecated.\n"));
169 dev = New(ftp_device);
183 dev->clear_slot(); /* unknown */
185 /* Copy user supplied device parameters from Resource */
186 dev->dev_name = get_memory(strlen(device->device_name)+1);
187 pm_strcpy(dev->dev_name, device->device_name);
188 dev->prt_name = get_memory(strlen(device->device_name) + strlen(device->hdr.name) + 20);
189 /* We edit "Resource-name" (physical-name) */
190 Mmsg(dev->prt_name, "\"%s\" (%s)", device->hdr.name, device->device_name);
191 Dmsg1(400, "Allocate dev=%s\n", dev->print_name());
192 dev->capabilities = device->cap_bits;
193 dev->min_free_space = device->min_free_space;
194 dev->min_block_size = device->min_block_size;
195 dev->max_block_size = device->max_block_size;
196 dev->max_volume_size = device->max_volume_size;
197 dev->max_file_size = device->max_file_size;
198 dev->max_concurrent_jobs = device->max_concurrent_jobs;
199 dev->volume_capacity = device->volume_capacity;
200 dev->max_rewind_wait = device->max_rewind_wait;
201 dev->max_open_wait = device->max_open_wait;
202 dev->vol_poll_interval = device->vol_poll_interval;
203 dev->max_spool_size = device->max_spool_size;
204 dev->drive_index = device->drive_index;
205 dev->enabled = device->enabled;
206 dev->autoselect = device->autoselect;
207 dev->read_only = device->read_only;
208 dev->dev_type = device->dev_type;
209 dev->device = device;
210 if (dev->is_tape()) { /* No parts on tapes */
211 dev->max_part_size = 0;
213 dev->max_part_size = device->max_part_size;
216 if (dev->vol_poll_interval && dev->vol_poll_interval < 60) {
217 dev->vol_poll_interval = 60;
221 /* The first time we create a DEVICE from the DEVRES, we keep a pointer
222 * to the DEVICE accessible from the DEVRES.
227 if (dev->is_fifo()) {
228 dev->capabilities |= CAP_STREAM; /* set stream device */
231 /* If the device requires mount :
232 * - Check that the mount point is available
233 * - Check that (un)mount commands are defined
235 if (dev->is_file() && dev->requires_mount()) {
236 if (!device->mount_point || stat(device->mount_point, &statp) < 0) {
238 dev->dev_errno = errno;
239 Jmsg2(jcr, M_ERROR_TERM, 0, _("Unable to stat mount point %s: ERR=%s\n"),
240 device->mount_point, be.bstrerror());
243 if (!device->mount_command || !device->unmount_command) {
244 Jmsg0(jcr, M_ERROR_TERM, 0, _("Mount and unmount commands must defined for a device which requires mount.\n"));
248 /* Keep the device ID in the DEVICE struct to identify the hardware */
249 if (dev->is_file() && stat(dev->archive_name(), &statp) == 0) {
250 dev->devno = statp.st_dev;
254 if (dev->max_block_size == 0) {
255 max_bs = DEFAULT_BLOCK_SIZE;
257 max_bs = dev->max_block_size;
259 if (dev->min_block_size > max_bs) {
260 Jmsg(jcr, M_ERROR_TERM, 0, _("Min block size > max on device %s\n"),
263 if (dev->max_block_size > 4096000) {
264 Jmsg3(jcr, M_ERROR, 0, _("Block size %u on device %s is too large, using default %u\n"),
265 dev->max_block_size, dev->print_name(), DEFAULT_BLOCK_SIZE);
266 dev->max_block_size = 0;
268 if (dev->max_block_size % TAPE_BSIZE != 0) {
269 Jmsg3(jcr, M_WARNING, 0, _("Max block size %u not multiple of device %s block size=%d.\n"),
270 dev->max_block_size, dev->print_name(), TAPE_BSIZE);
272 if (dev->max_volume_size != 0 && dev->max_volume_size < (dev->max_block_size << 4)) {
273 Jmsg(jcr, M_ERROR_TERM, 0, _("Max Vol Size < 8 * Max Block Size for device %s\n"),
277 dev->errmsg = get_pool_memory(PM_EMSG);
280 if ((errstat = dev->init_mutex()) != 0) {
282 dev->dev_errno = errstat;
283 Mmsg1(dev->errmsg, _("Unable to init mutex: ERR=%s\n"), be.bstrerror(errstat));
284 Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
286 if ((errstat = pthread_cond_init(&dev->wait, NULL)) != 0) {
288 dev->dev_errno = errstat;
289 Mmsg1(dev->errmsg, _("Unable to init cond variable: ERR=%s\n"), be.bstrerror(errstat));
290 Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
292 if ((errstat = pthread_cond_init(&dev->wait_next_vol, NULL)) != 0) {
294 dev->dev_errno = errstat;
295 Mmsg1(dev->errmsg, _("Unable to init cond variable: ERR=%s\n"), be.bstrerror(errstat));
296 Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
298 if ((errstat = pthread_mutex_init(&dev->spool_mutex, NULL)) != 0) {
300 dev->dev_errno = errstat;
301 Mmsg1(dev->errmsg, _("Unable to init spool mutex: ERR=%s\n"), be.bstrerror(errstat));
302 Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
304 if ((errstat = dev->init_acquire_mutex()) != 0) {
306 dev->dev_errno = errstat;
307 Mmsg1(dev->errmsg, _("Unable to init acquire mutex: ERR=%s\n"), be.bstrerror(errstat));
308 Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
310 if ((errstat = dev->init_read_acquire_mutex()) != 0) {
312 dev->dev_errno = errstat;
313 Mmsg1(dev->errmsg, _("Unable to init read acquire mutex: ERR=%s\n"), be.bstrerror(errstat));
314 Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
316 if ((errstat = dev->init_volcat_mutex()) != 0) {
318 dev->dev_errno = errstat;
319 Mmsg1(dev->errmsg, _("Unable to init volcat mutex: ERR=%s\n"), be.bstrerror(errstat));
320 Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
322 if ((errstat = dev->init_dcrs_mutex()) != 0) {
324 dev->dev_errno = errstat;
325 Mmsg1(dev->errmsg, _("Unable to init dcrs mutex: ERR=%s\n"), be.bstrerror(errstat));
326 Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
329 dev->set_mutex_priorities();
332 if ((errstat = rwl_init(&dev->lock)) != 0) {
334 dev->dev_errno = errstat;
335 Mmsg1(dev->errmsg, _("Unable to init mutex: ERR=%s\n"), be.bstrerror(errstat));
336 Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
341 dev->attached_dcrs = New(dlist(dcr, &dcr->dev_link));
342 Dmsg2(100, "init_dev: tape=%d dev_name=%s\n", dev->is_tape(), dev->dev_name);
343 dev->initiated = true;
349 * Open the device with the operating system and
350 * initialize buffer pointers.
352 * Returns: true on success
355 * Note, for a tape, the VolName is the name we give to the
356 * volume (not really used here), but for a file, the
357 * VolName represents the name of the file to be created/opened.
358 * In the case of a file, the full name is the device name
359 * (archive_name) with the VolName concatenated.
361 bool DEVICE::open(DCR *dcr, int omode)
365 if (openmode == omode) {
368 Dmsg1(200, "Close fd=%d for mode change in open().\n", m_fd);
371 preserve = state & (ST_LABEL|ST_APPEND|ST_READ);
375 dcr->setVolCatName(dcr->VolumeName);
376 VolCatInfo = dcr->VolCatInfo; /* structure assign */
379 state &= ~(ST_NOSPACE|ST_LABEL|ST_APPEND|ST_READ|ST_EOT|ST_WEOT|ST_EOF);
380 label_type = B_BACULA_LABEL;
382 if (is_tape() || is_fifo()) {
383 open_tape_device(dcr, omode);
384 } else if (is_ftp()) {
385 open_device(dcr, omode);
387 Dmsg1(100, "call open_file_device mode=%s\n", mode_to_str(omode));
388 open_file_device(dcr, omode);
390 state |= preserve; /* reset any important state info */
391 Dmsg2(100, "preserve=0x%x fd=%d\n", preserve, m_fd);
393 Dmsg7(100, "open dev: fd=%d dev=%p dcr=%p vol=%s type=%d dev_name=%s mode=%s\n",
394 m_fd, getVolCatName(), this, dcr, dev_type, print_name(), mode_to_str(omode));
398 void DEVICE::set_mode(int new_mode)
401 case CREATE_READ_WRITE:
402 mode = O_CREAT | O_RDWR | O_BINARY;
404 case OPEN_READ_WRITE:
405 mode = O_RDWR | O_BINARY;
408 mode = O_RDONLY | O_BINARY;
410 case OPEN_WRITE_ONLY:
411 mode = O_WRONLY | O_BINARY;
414 Emsg0(M_ABORT, 0, _("Illegal mode given to open dev.\n"));
419 void DEVICE::open_device(DCR *dcr, int omode)
421 /* do nothing waiting to split open_file/tape_device */
426 * Called to indicate that we have just read an
427 * EOF from the device.
429 void DEVICE::set_ateof()
441 * Called to indicate we are now at the end of the tape, and
442 * writing is not possible.
444 void DEVICE::set_ateot()
446 /* Make tape effectively read-only */
447 Dmsg0(200, "==== Set AtEof\n");
448 state |= (ST_EOF|ST_EOT|ST_WEOT);
454 * Set the position of the device -- only for files and DVD
455 * For other devices, there is no generic way to do it.
456 * Returns: true on succes
459 bool DEVICE::update_pos(DCR *dcr)
466 Mmsg0(errmsg, _("Bad device call. Device not open\n"));
467 Emsg1(M_FATAL, 0, "%s", errmsg);
474 pos = lseek(dcr, (boffset_t)0, SEEK_CUR);
478 Pmsg1(000, _("Seek error: ERR=%s\n"), be.bstrerror());
479 Mmsg2(errmsg, _("lseek error on %s. ERR=%s.\n"),
480 print_name(), be.bstrerror());
484 block_num = (uint32_t)pos;
485 file = (uint32_t)(pos >> 32);
491 void DEVICE::set_slot(int32_t slot)
494 if (vol) vol->clear_slot();
497 void DEVICE::clear_slot()
500 if (vol) vol->set_slot(-1);
503 const char *DEVICE::print_type() const
505 return prt_dev_types[device->dev_type];
509 * Set to unload the current volume in the drive
511 void DEVICE::set_unload()
513 if (!m_unload && VolHdr.VolumeName[0] != 0) {
515 memcpy(UnloadVolName, VolHdr.VolumeName, sizeof(UnloadVolName));
516 notify_newvol_in_attached_dcrs(NULL);
521 * Clear volume header
523 void DEVICE::clear_volhdr()
525 Dmsg1(100, "Clear volhdr vol=%s\n", VolHdr.VolumeName);
526 memset(&VolHdr, 0, sizeof(VolHdr));
527 setVolCatInfo(false);
530 void DEVICE::set_nospace()
535 void DEVICE::clear_nospace()
537 state &= ~ST_NOSPACE;
540 /* Put device in append mode */
541 void DEVICE::set_append()
543 state &= ~(ST_NOSPACE|ST_READ|ST_EOT|ST_EOF|ST_WEOT); /* remove EOF/EOT flags */
547 /* Clear append mode */
548 void DEVICE::clear_append()
553 /* Put device in read mode */
554 void DEVICE::set_read()
556 state &= ~(ST_APPEND|ST_EOT|ST_EOF|ST_WEOT); /* remove EOF/EOT flags */
560 /* Clear read mode */
561 void DEVICE::clear_read()
567 * Get freespace using OS calls
568 * TODO: See if it's working with mount commands
570 bool DEVICE::get_os_device_freespace()
572 int64_t freespace, totalspace;
577 if (fs_get_free_space(dev_name, &freespace, &totalspace) == 0) {
578 set_freespace(freespace, totalspace, 0, true);
583 set_freespace(0, 0, 0, false); /* No valid freespace */
588 /* Update the free space on the device */
589 bool DEVICE::update_freespace()
591 POOL_MEM ocmd(PM_FNAME);
595 uint64_t free, total;
606 /* The device must be mounted in order for freespace to work */
607 if (requires_mount()) {
611 if (get_os_device_freespace()) {
612 Dmsg4(20, "get_os_device_freespace: free_space=%s freespace_ok=%d free_space_errno=%d have_media=%d\n",
613 edit_uint64(free_space, ed1), !!is_freespace_ok(), free_space_errno, !!have_media());
617 icmd = device->free_space_command;
620 set_freespace(0, 0, 0, false);
621 Dmsg2(20, "ERROR: update_free_space_dev: free_space=%s, free_space_errno=%d (!icmd)\n",
622 edit_uint64(free_space, ed1), free_space_errno);
623 Mmsg(errmsg, _("No FreeSpace command defined.\n"));
627 edit_mount_codes(ocmd, icmd);
629 Dmsg1(20, "update_freespace: cmd=%s\n", ocmd.c_str());
631 results = get_pool_memory(PM_MESSAGE);
633 Dmsg1(20, "Run freespace prog=%s\n", ocmd.c_str());
634 status = run_program_full_output(ocmd.c_str(), max_open_wait/2, results);
635 Dmsg2(20, "Freespace status=%d result=%s\n", status, results);
636 /* Should report "1223232 12323232\n" "free total\n" */
638 free = str_to_int64(results) * 1024;
641 if (skip_nonspaces(&p)) {
642 total = str_to_int64(p) * 1024;
648 Dmsg1(400, "Free space program run: Freespace=%s\n", results);
650 set_freespace(free, total, 0, true); /* have valid freespace */
655 set_freespace(0, 0, EPIPE, false); /* no valid freespace */
656 Mmsg2(errmsg, _("Cannot run free space command. Results=%s ERR=%s\n"),
657 results, be.bstrerror(status));
659 dev_errno = free_space_errno;
660 Dmsg4(20, "Cannot get free space on device %s. free_space=%s, "
661 "free_space_errno=%d ERR=%s\n",
662 print_name(), edit_uint64(free_space, ed1),
663 free_space_errno, errmsg);
665 free_pool_memory(results);
666 Dmsg4(20, "leave update_freespace: free_space=%s freespace_ok=%d free_space_errno=%d have_media=%d\n",
667 edit_uint64(free_space, ed1), !!is_freespace_ok(), free_space_errno, !!have_media());
671 void DEVICE::updateVolCatBytes(uint64_t bytes)
675 dev->VolCatInfo.VolCatAmetaBytes += bytes;
676 Dmsg1(200, "updateVolBytes ameta=%lld\n",
677 dev->VolCatInfo.VolCatAmetaBytes);
678 dev->VolCatInfo.VolCatBytes += bytes;
679 setVolCatInfo(false);
683 void DEVICE::updateVolCatBlocks(uint32_t blocks)
687 dev->VolCatInfo.VolCatAmetaBlocks += blocks;
688 dev->VolCatInfo.VolCatBlocks += blocks;
689 setVolCatInfo(false);
694 void DEVICE::updateVolCatWrites(uint32_t writes)
698 dev->VolCatInfo.VolCatAmetaWrites += writes;
699 dev->VolCatInfo.VolCatWrites += writes;
700 setVolCatInfo(false);
704 void DEVICE::updateVolCatReads(uint32_t reads)
708 dev->VolCatInfo.VolCatAmetaReads += reads;
709 dev->VolCatInfo.VolCatReads += reads;
710 setVolCatInfo(false);
714 void DEVICE::updateVolCatReadBytes(uint64_t bytes)
718 dev->VolCatInfo.VolCatAmetaRBytes += bytes;
719 dev->VolCatInfo.VolCatRBytes += bytes;
720 setVolCatInfo(false);
731 Dmsg4(40, "close_dev vol=%s fd=%d dev=%p dev=%s\n",
732 VolHdr.VolumeName, m_fd, this, print_name());
736 Dmsg2(200, "device %s already closed vol=%s\n", print_name(),
738 return true; /* already closed */
746 /* Fall through wanted */
748 if (d_close(m_fd) != 0) {
751 Mmsg2(errmsg, _("Error closing device %s. ERR=%s.\n"),
752 print_name(), be.bstrerror());
758 unmount(1); /* do unmount if required */
760 /* Clean up device packet so it can be reused */
764 * Be careful not to clear items needed by the DVD driver
765 * when it is closing a single part.
767 state &= ~(ST_LABEL|ST_READ|ST_APPEND|ST_EOT|ST_WEOT|ST_EOF|
768 ST_NOSPACE|ST_MOUNTED|ST_MEDIA|ST_SHORT);
769 label_type = B_BACULA_LABEL;
770 file = block_num = 0;
773 EndFile = EndBlock = 0;
776 memset(&VolCatInfo, 0, sizeof(VolCatInfo));
778 stop_thread_timer(tid);
785 * This call closes the device, but it is used in DVD handling
786 * where we close one part and then open the next part. The
787 * difference between close_part() and close() is that close_part()
788 * saves the state information of the device (e.g. the Volume lable,
789 * the Volume Catalog record, ... This permits opening and closing
790 * the Volume parts multiple times without losing track of what the
791 * main Volume parameters are.
793 void DEVICE::close_part(DCR * /*dcr*/)
795 VOLUME_LABEL saveVolHdr;
796 VOLUME_CAT_INFO saveVolCatInfo; /* Volume Catalog Information */
799 saveVolHdr = VolHdr; /* structure assignment */
800 saveVolCatInfo = VolCatInfo; /* structure assignment */
801 close(); /* close current part */
802 VolHdr = saveVolHdr; /* structure assignment */
803 VolCatInfo = saveVolCatInfo; /* structure assignment */
807 * If timeout, wait until the mount command returns 0.
808 * If !timeout, try to mount the device only once.
810 bool DEVICE::mount(int timeout)
812 Dmsg0(190, "Enter mount\n");
813 if (!is_mounted() && device->mount_command) {
814 return mount_file(1, timeout);
821 * If timeout, wait until the unmount command returns 0.
822 * If !timeout, try to unmount the device only once.
824 bool DEVICE::unmount(int timeout)
826 Dmsg0(100, "Enter unmount\n");
827 if (is_mounted() && requires_mount() && device->unmount_command) {
828 return mount_file(0, timeout);
835 * Edit codes into (Un)MountCommand, Write(First)PartCommand
837 * %a = archive device name
838 * %e = erase (set if cannot mount and first part)
841 * %v = last part name
843 * omsg = edited output message
844 * imsg = input string containing edit codes (%x)
847 void DEVICE::edit_mount_codes(POOL_MEM &omsg, const char *imsg)
853 POOL_MEM archive_name(PM_FNAME);
856 Dmsg1(800, "edit_mount_codes: %s\n", imsg);
857 for (p=imsg; *p; p++) {
867 if (num_dvd_parts == 0) {
868 if (truncating || blank_dvd) {
878 bsnprintf(add, sizeof(add), "%d", part);
882 str = device->mount_point;
896 Dmsg1(1900, "add_str %s\n", str);
897 pm_strcat(omsg, (char *)str);
898 Dmsg1(1800, "omsg=%s\n", omsg.c_str());
902 /* return the last timer interval (ms)
903 * or 0 if something goes wrong
905 btime_t DEVICE::get_timer_count()
907 btime_t temp = last_timer;
908 last_timer = get_current_btime();
909 temp = last_timer - temp; /* get elapsed time */
910 return (temp>0)?temp:0; /* take care of skewed clock */
914 ssize_t DEVICE::read(void *buf, size_t len)
920 read_len = d_read(m_fd, buf, len);
922 last_tick = get_timer_count();
924 DevReadTime += last_tick;
925 VolCatInfo.VolReadTime += last_tick;
927 if (read_len > 0) { /* skip error */
928 DevReadBytes += read_len;
935 ssize_t DEVICE::write(const void *buf, size_t len)
941 write_len = d_write(m_fd, buf, len);
943 last_tick = get_timer_count();
945 DevWriteTime += last_tick;
946 VolCatInfo.VolWriteTime += last_tick;
948 if (write_len > 0) { /* skip error */
949 DevWriteBytes += write_len;
955 /* Return the resource name for the device */
956 const char *DEVICE::name() const
958 return device->hdr.name;
961 uint32_t DEVICE::get_file()
963 if (is_dvd() || is_tape()) {
966 uint64_t bytes = VolCatInfo.VolCatAdataBytes + VolCatInfo.VolCatAmetaBytes;
967 return (uint32_t)(bytes >> 32);
971 uint32_t DEVICE::get_block_num()
973 if (is_dvd() || is_tape()) {
976 return VolCatInfo.VolCatAdataBlocks + VolCatInfo.VolCatAmetaBlocks;
981 * Walk through all attached jcrs indicating the volume has changed
982 * Note: If you have the new VolumeName, it is passed here,
983 * otherwise pass a NULL.
986 DEVICE::notify_newvol_in_attached_dcrs(const char *newVolumeName)
988 Dmsg2(140, "Notify dcrs of vol change. oldVolume=%s NewVolume=%s\n",
989 getVolCatName(), newVolumeName?"*None*":newVolumeName);
992 foreach_dlist(mdcr, attached_dcrs) {
993 if (mdcr->jcr->JobId == 0) {
994 continue; /* ignore console */
997 mdcr->NewFile = true;
998 if (newVolumeName && mdcr->VolumeName != newVolumeName) {
999 bstrncpy(mdcr->VolumeName, newVolumeName, sizeof(mdcr->VolumeName));
1000 Dmsg2(140, "Set NewVol=%s in JobId=%d\n", mdcr->VolumeName, mdcr->jcr->JobId);
1007 * Walk through all attached jcrs indicating the File has changed
1010 DEVICE::notify_newfile_in_attached_dcrs()
1012 Dmsg1(140, "Notify dcrs of file change. Volume=%s\n", getVolCatName());
1015 foreach_dlist(mdcr, attached_dcrs) {
1016 if (mdcr->jcr->JobId == 0) {
1017 continue; /* ignore console */
1019 Dmsg1(140, "Notify JobI=%d\n", mdcr->jcr->JobId);
1020 mdcr->NewFile = true;
1028 * Free memory allocated for the device
1030 void DEVICE::term(void)
1033 Dmsg1(900, "term dev: %s\n", print_name());
1036 free_memory(dev_name);
1040 free_memory(prt_name);
1044 free_pool_memory(errmsg);
1047 pthread_mutex_destroy(&m_mutex);
1048 pthread_cond_destroy(&wait);
1049 pthread_cond_destroy(&wait_next_vol);
1050 pthread_mutex_destroy(&spool_mutex);
1051 pthread_mutex_destroy(&freespace_mutex);
1052 if (attached_dcrs) {
1053 delete attached_dcrs;
1054 attached_dcrs = NULL;
1056 /* We let the DEVRES pointer if not our device */
1057 if (device && device->dev == this) {
1066 /* Get freespace values */
1067 void DEVICE::get_freespace(uint64_t *freeval, uint64_t *totalval)
1069 get_os_device_freespace();
1071 if (is_freespace_ok()) {
1072 *freeval = free_space;
1073 *totalval = total_space;
1075 *freeval = *totalval = 0;
1080 /* Set freespace values */
1081 void DEVICE::set_freespace(uint64_t freeval, uint64_t totalval, int errnoval, bool valid)
1084 free_space = freeval;
1085 total_space = totalval;
1086 free_space_errno = errnoval;
1090 clear_freespace_ok();
1096 * This routine initializes the device wait timers
1098 void init_device_wait_timers(DCR *dcr)
1100 DEVICE *dev = dcr->dev;
1101 JCR *jcr = dcr->jcr;
1103 /* ******FIXME******* put these on config variables */
1104 dev->min_wait = 60 * 60;
1105 dev->max_wait = 24 * 60 * 60;
1106 dev->max_num_wait = 9; /* 5 waits =~ 1 day, then 1 day at a time */
1107 dev->wait_sec = dev->min_wait;
1108 dev->rem_wait_sec = dev->wait_sec;
1112 jcr->min_wait = 60 * 60;
1113 jcr->max_wait = 24 * 60 * 60;
1114 jcr->max_num_wait = 9; /* 5 waits =~ 1 day, then 1 day at a time */
1115 jcr->wait_sec = jcr->min_wait;
1116 jcr->rem_wait_sec = jcr->wait_sec;
1121 void init_jcr_device_wait_timers(JCR *jcr)
1123 /* ******FIXME******* put these on config variables */
1124 jcr->min_wait = 60 * 60;
1125 jcr->max_wait = 24 * 60 * 60;
1126 jcr->max_num_wait = 9; /* 5 waits =~ 1 day, then 1 day at a time */
1127 jcr->wait_sec = jcr->min_wait;
1128 jcr->rem_wait_sec = jcr->wait_sec;
1134 * The dev timers are used for waiting on a particular device
1136 * Returns: true if time doubled
1137 * false if max time expired
1139 bool double_dev_wait_time(DEVICE *dev)
1141 dev->wait_sec *= 2; /* double wait time */
1142 if (dev->wait_sec > dev->max_wait) { /* but not longer than maxtime */
1143 dev->wait_sec = dev->max_wait;
1146 dev->rem_wait_sec = dev->wait_sec;
1147 if (dev->num_wait >= dev->max_num_wait) {
1153 static const char *modes[] = {
1154 "CREATE_READ_WRITE",
1161 const char *mode_to_str(int mode)
1163 static char buf[100];
1164 if (mode < 1 || mode > 4) {
1165 bsnprintf(buf, sizeof(buf), "BAD mode=%d", mode);
1168 return modes[mode-1];