2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2015 Kern Sibbald
5 Copyright (C) 2000-2014 Free Software Foundation Europe e.V.
7 The original author of Bacula is Kern Sibbald, with contributions
8 from many others, a complete list can be found in the file AUTHORS.
10 You may use this file and others of this release according to the
11 license defined in the LICENSE file, which includes the Affero General
12 Public License, v3.0 ("AGPLv3") and some additional permissions and
13 terms pursuant to its AGPLv3 Section 7.
15 This notice must be preserved when any source code is
16 conveyed and/or propagated.
18 Bacula(R) is a registered trademark of Kern Sibbald.
22 * dev.c -- low level operations on device (storage device)
24 * written by, Kern Sibbald, MM
26 * NOTE!!!! None of these routines are reentrant. You must
27 * use dev->rLock() and dev->Unlock() at a higher level,
28 * or use the xxx_device() equivalents. By moving the
29 * thread synchronization to a higher level, we permit
30 * the higher level routines to "seize" the device and
31 * to carry out operations without worrying about who
32 * set what lock (i.e. race conditions).
34 * Note, this is the device dependent code, and may have
35 * to be modified for each system, but is meant to
36 * be as "generic" as possible.
38 * The purpose of this code is to develop a SIMPLE Storage
39 * daemon. More complicated coding (double buffering, writer
40 * thread, ...) is left for a later version.
45 * Handling I/O errors and end of tape conditions are a bit tricky.
46 * This is how it is currently done when writing.
47 * On either an I/O error or end of tape,
48 * we will stop writing on the physical device (no I/O recovery is
49 * attempted at least in this daemon). The state flag will be sent
50 * to include ST_EOT, which is ephemeral, and ST_WEOT, which is
51 * persistent. Lots of routines clear ST_EOT, but ST_WEOT is
52 * cleared only when the problem goes away. Now when ST_WEOT
53 * is set all calls to write_block_to_device() call the fix_up
54 * routine. In addition, all threads are blocked
55 * from writing on the tape by calling lock_dev(), and thread other
56 * than the first thread to hit the EOT will block on a condition
57 * variable. The first thread to hit the EOT will continue to
58 * be able to read and write the tape (he sort of tunnels through
59 * the locking mechanism -- see lock_dev() for details).
61 * Now presumably somewhere higher in the chain of command
62 * (device.c), someone will notice the EOT condition and
63 * get a new tape up, get the tape label read, and mark
64 * the label for rewriting. Then this higher level routine
65 * will write the unwritten buffer to the new volume.
66 * Finally, he will release
67 * any blocked threads by doing a broadcast on the condition
68 * variable. At that point, we should be totally back in
69 * business with no lost data.
79 /* Imported functions */
80 extern void set_os_device_parameters(DCR *dcr);
81 extern bool dev_get_os_pos(DEVICE *dev, struct mtget *mt_stat);
82 extern uint32_t status_dev(DEVICE *dev);
84 /* Forward referenced functions */
85 const char *mode_to_str(int mode);
86 DEVICE *m_init_dev(JCR *jcr, DEVRES *device);
88 * Device types for printing
90 static const char *prt_dev_types[] = {
102 * Allocate and initialize the DEVICE structure
103 * Note, if dev is non-NULL, it is already allocated,
104 * thus we neither allocate it nor free it. This allows
105 * the caller to put the packet in shared memory.
107 * Note, for a tape, the device->device_name is the device name
108 * (e.g. /dev/nst0), and for a file, the device name
109 * is the directory in which the file will be placed.
112 DEVICE *init_dev(JCR *jcr, DEVRES *device)
114 generate_global_plugin_event(bsdGlobalEventDeviceInit, device);
115 DEVICE *dev = m_init_dev(jcr, device);
119 DEVICE *m_init_dev(JCR *jcr, DEVRES *device)
127 /* If no device type specified, try to guess */
128 if (!device->dev_type) {
129 /* Check that device is available */
130 if (stat(device->device_name, &statp) < 0) {
132 Jmsg2(jcr, M_ERROR, 0, _("Unable to stat device %s: ERR=%s\n"),
133 device->device_name, be.bstrerror());
136 if (S_ISDIR(statp.st_mode)) {
137 device->dev_type = B_FILE_DEV;
138 } else if (S_ISCHR(statp.st_mode)) {
139 device->dev_type = B_TAPE_DEV;
140 } else if (S_ISFIFO(statp.st_mode)) {
141 device->dev_type = B_FIFO_DEV;
143 /* must set DeviceType = Vtape
144 * in normal mode, autodetection is disabled
146 } else if (S_ISREG(statp.st_mode)) {
147 device->dev_type = B_VTAPE_DEV;
149 } else if (!(device->cap_bits & CAP_REQMOUNT)) {
150 Jmsg2(jcr, M_ERROR, 0, _("%s is an unknown device type. Must be tape or directory\n"
151 " or have RequiresMount=yes for DVD. st_mode=%x\n"),
152 device->device_name, statp.st_mode);
155 device->dev_type = B_DVD_DEV;
157 if (strcmp(device->device_name, "/dev/null") == 0) {
158 device->dev_type = B_NULL_DEV;
161 switch (device->dev_type) {
163 Jmsg0(jcr, M_FATAL, 0, _("DVD support is now deprecated.\n"));
170 dev = New(ftp_device);
184 dev->clear_slot(); /* unknown */
186 /* Copy user supplied device parameters from Resource */
187 dev->dev_name = get_memory(strlen(device->device_name)+1);
188 pm_strcpy(dev->dev_name, device->device_name);
189 dev->prt_name = get_memory(strlen(device->device_name) + strlen(device->hdr.name) + 20);
190 /* We edit "Resource-name" (physical-name) */
191 Mmsg(dev->prt_name, "\"%s\" (%s)", device->hdr.name, device->device_name);
192 Dmsg1(400, "Allocate dev=%s\n", dev->print_name());
193 dev->capabilities = device->cap_bits;
194 dev->min_free_space = device->min_free_space;
195 dev->min_block_size = device->min_block_size;
196 dev->max_block_size = device->max_block_size;
197 dev->max_volume_size = device->max_volume_size;
198 dev->max_file_size = device->max_file_size;
199 dev->max_concurrent_jobs = device->max_concurrent_jobs;
200 dev->volume_capacity = device->volume_capacity;
201 dev->max_rewind_wait = device->max_rewind_wait;
202 dev->max_open_wait = device->max_open_wait;
203 dev->vol_poll_interval = device->vol_poll_interval;
204 dev->max_spool_size = device->max_spool_size;
205 dev->drive_index = device->drive_index;
206 dev->enabled = device->enabled;
207 dev->autoselect = device->autoselect;
208 dev->read_only = device->read_only;
209 dev->dev_type = device->dev_type;
210 dev->device = device;
211 if (dev->is_tape()) { /* No parts on tapes */
212 dev->max_part_size = 0;
214 dev->max_part_size = device->max_part_size;
217 if (dev->vol_poll_interval && dev->vol_poll_interval < 60) {
218 dev->vol_poll_interval = 60;
222 /* The first time we create a DEVICE from the DEVRES, we keep a pointer
223 * to the DEVICE accessible from the DEVRES.
228 if (dev->is_fifo()) {
229 dev->capabilities |= CAP_STREAM; /* set stream device */
232 /* If the device requires mount :
233 * - Check that the mount point is available
234 * - Check that (un)mount commands are defined
236 if (dev->is_file() && dev->requires_mount()) {
237 if (!device->mount_point || stat(device->mount_point, &statp) < 0) {
239 dev->dev_errno = errno;
240 Jmsg2(jcr, M_ERROR_TERM, 0, _("Unable to stat mount point %s: ERR=%s\n"),
241 device->mount_point, be.bstrerror());
244 if (!device->mount_command || !device->unmount_command) {
245 Jmsg0(jcr, M_ERROR_TERM, 0, _("Mount and unmount commands must defined for a device which requires mount.\n"));
249 /* Keep the device ID in the DEVICE struct to identify the hardware */
250 if (dev->is_file() && stat(dev->archive_name(), &statp) == 0) {
251 dev->devno = statp.st_dev;
255 if (dev->max_block_size == 0) {
256 max_bs = DEFAULT_BLOCK_SIZE;
258 max_bs = dev->max_block_size;
260 if (dev->min_block_size > max_bs) {
261 Jmsg(jcr, M_ERROR_TERM, 0, _("Min block size > max on device %s\n"),
264 if (dev->max_block_size > 4096000) {
265 Jmsg3(jcr, M_ERROR, 0, _("Block size %u on device %s is too large, using default %u\n"),
266 dev->max_block_size, dev->print_name(), DEFAULT_BLOCK_SIZE);
267 dev->max_block_size = 0;
269 if (dev->max_block_size % TAPE_BSIZE != 0) {
270 Jmsg3(jcr, M_WARNING, 0, _("Max block size %u not multiple of device %s block size=%d.\n"),
271 dev->max_block_size, dev->print_name(), TAPE_BSIZE);
273 if (dev->max_volume_size != 0 && dev->max_volume_size < (dev->max_block_size << 4)) {
274 Jmsg(jcr, M_ERROR_TERM, 0, _("Max Vol Size < 8 * Max Block Size for device %s\n"),
278 dev->errmsg = get_pool_memory(PM_EMSG);
281 if ((errstat = dev->init_mutex()) != 0) {
283 dev->dev_errno = errstat;
284 Mmsg1(dev->errmsg, _("Unable to init mutex: ERR=%s\n"), be.bstrerror(errstat));
285 Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
287 if ((errstat = pthread_cond_init(&dev->wait, NULL)) != 0) {
289 dev->dev_errno = errstat;
290 Mmsg1(dev->errmsg, _("Unable to init cond variable: ERR=%s\n"), be.bstrerror(errstat));
291 Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
293 if ((errstat = pthread_cond_init(&dev->wait_next_vol, NULL)) != 0) {
295 dev->dev_errno = errstat;
296 Mmsg1(dev->errmsg, _("Unable to init cond variable: ERR=%s\n"), be.bstrerror(errstat));
297 Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
299 if ((errstat = pthread_mutex_init(&dev->spool_mutex, NULL)) != 0) {
301 dev->dev_errno = errstat;
302 Mmsg1(dev->errmsg, _("Unable to init spool mutex: ERR=%s\n"), be.bstrerror(errstat));
303 Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
305 if ((errstat = dev->init_acquire_mutex()) != 0) {
307 dev->dev_errno = errstat;
308 Mmsg1(dev->errmsg, _("Unable to init acquire mutex: ERR=%s\n"), be.bstrerror(errstat));
309 Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
311 if ((errstat = dev->init_read_acquire_mutex()) != 0) {
313 dev->dev_errno = errstat;
314 Mmsg1(dev->errmsg, _("Unable to init read acquire mutex: ERR=%s\n"), be.bstrerror(errstat));
315 Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
317 if ((errstat = dev->init_volcat_mutex()) != 0) {
319 dev->dev_errno = errstat;
320 Mmsg1(dev->errmsg, _("Unable to init volcat mutex: ERR=%s\n"), be.bstrerror(errstat));
321 Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
323 if ((errstat = dev->init_dcrs_mutex()) != 0) {
325 dev->dev_errno = errstat;
326 Mmsg1(dev->errmsg, _("Unable to init dcrs mutex: ERR=%s\n"), be.bstrerror(errstat));
327 Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
330 dev->set_mutex_priorities();
333 if ((errstat = rwl_init(&dev->lock)) != 0) {
335 dev->dev_errno = errstat;
336 Mmsg1(dev->errmsg, _("Unable to init mutex: ERR=%s\n"), be.bstrerror(errstat));
337 Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
342 dev->attached_dcrs = New(dlist(dcr, &dcr->dev_link));
343 Dmsg2(100, "init_dev: tape=%d dev_name=%s\n", dev->is_tape(), dev->dev_name);
344 dev->initiated = true;
350 * Open the device with the operating system and
351 * initialize buffer pointers.
353 * Returns: true on success
356 * Note, for a tape, the VolName is the name we give to the
357 * volume (not really used here), but for a file, the
358 * VolName represents the name of the file to be created/opened.
359 * In the case of a file, the full name is the device name
360 * (archive_name) with the VolName concatenated.
362 bool DEVICE::open(DCR *dcr, int omode)
366 if (openmode == omode) {
369 Dmsg1(200, "Close fd=%d for mode change in open().\n", m_fd);
372 preserve = state & (ST_LABEL|ST_APPEND|ST_READ);
376 dcr->setVolCatName(dcr->VolumeName);
377 VolCatInfo = dcr->VolCatInfo; /* structure assign */
380 state &= ~(ST_NOSPACE|ST_LABEL|ST_APPEND|ST_READ|ST_EOT|ST_WEOT|ST_EOF);
381 label_type = B_BACULA_LABEL;
383 if (is_tape() || is_fifo()) {
384 open_tape_device(dcr, omode);
385 } else if (is_ftp()) {
386 open_device(dcr, omode);
388 Dmsg1(100, "call open_file_device mode=%s\n", mode_to_str(omode));
389 open_file_device(dcr, omode);
391 state |= preserve; /* reset any important state info */
392 Dmsg2(100, "preserve=0x%x fd=%d\n", preserve, m_fd);
394 Dmsg7(100, "open dev: fd=%d dev=%p dcr=%p vol=%s type=%d dev_name=%s mode=%s\n",
395 m_fd, getVolCatName(), this, dcr, dev_type, print_name(), mode_to_str(omode));
399 void DEVICE::set_mode(int new_mode)
402 case CREATE_READ_WRITE:
403 mode = O_CREAT | O_RDWR | O_BINARY;
405 case OPEN_READ_WRITE:
406 mode = O_RDWR | O_BINARY;
409 mode = O_RDONLY | O_BINARY;
411 case OPEN_WRITE_ONLY:
412 mode = O_WRONLY | O_BINARY;
415 Emsg0(M_ABORT, 0, _("Illegal mode given to open dev.\n"));
420 void DEVICE::open_device(DCR *dcr, int omode)
422 /* do nothing waiting to split open_file/tape_device */
427 * Called to indicate that we have just read an
428 * EOF from the device.
430 void DEVICE::set_ateof()
442 * Called to indicate we are now at the end of the tape, and
443 * writing is not possible.
445 void DEVICE::set_ateot()
447 /* Make tape effectively read-only */
448 Dmsg0(200, "==== Set AtEof\n");
449 state |= (ST_EOF|ST_EOT|ST_WEOT);
455 * Set the position of the device -- only for files and DVD
456 * For other devices, there is no generic way to do it.
457 * Returns: true on succes
460 bool DEVICE::update_pos(DCR *dcr)
467 Mmsg0(errmsg, _("Bad device call. Device not open\n"));
468 Emsg1(M_FATAL, 0, "%s", errmsg);
475 pos = lseek(dcr, (boffset_t)0, SEEK_CUR);
479 Pmsg1(000, _("Seek error: ERR=%s\n"), be.bstrerror());
480 Mmsg2(errmsg, _("lseek error on %s. ERR=%s.\n"),
481 print_name(), be.bstrerror());
485 block_num = (uint32_t)pos;
486 file = (uint32_t)(pos >> 32);
492 void DEVICE::set_slot(int32_t slot)
495 if (vol) vol->clear_slot();
498 void DEVICE::clear_slot()
501 if (vol) vol->set_slot(-1);
504 const char *DEVICE::print_type() const
506 return prt_dev_types[device->dev_type];
510 * Set to unload the current volume in the drive
512 void DEVICE::set_unload()
514 if (!m_unload && VolHdr.VolumeName[0] != 0) {
516 memcpy(UnloadVolName, VolHdr.VolumeName, sizeof(UnloadVolName));
517 notify_newvol_in_attached_dcrs(NULL);
522 * Clear volume header
524 void DEVICE::clear_volhdr()
526 Dmsg1(100, "Clear volhdr vol=%s\n", VolHdr.VolumeName);
527 memset(&VolHdr, 0, sizeof(VolHdr));
528 setVolCatInfo(false);
531 void DEVICE::set_nospace()
536 void DEVICE::clear_nospace()
538 state &= ~ST_NOSPACE;
541 /* Put device in append mode */
542 void DEVICE::set_append()
544 state &= ~(ST_NOSPACE|ST_READ|ST_EOT|ST_EOF|ST_WEOT); /* remove EOF/EOT flags */
548 /* Clear append mode */
549 void DEVICE::clear_append()
554 /* Put device in read mode */
555 void DEVICE::set_read()
557 state &= ~(ST_APPEND|ST_EOT|ST_EOF|ST_WEOT); /* remove EOF/EOT flags */
561 /* Clear read mode */
562 void DEVICE::clear_read()
568 * Get freespace using OS calls
569 * TODO: See if it's working with mount commands
571 bool DEVICE::get_os_device_freespace()
573 int64_t freespace, totalspace;
578 if (fs_get_free_space(dev_name, &freespace, &totalspace) == 0) {
579 set_freespace(freespace, totalspace, 0, true);
584 set_freespace(0, 0, 0, false); /* No valid freespace */
589 /* Update the free space on the device */
590 bool DEVICE::update_freespace()
592 POOL_MEM ocmd(PM_FNAME);
596 uint64_t free, total;
607 /* The device must be mounted in order for freespace to work */
608 if (requires_mount()) {
612 if (get_os_device_freespace()) {
613 Dmsg4(20, "get_os_device_freespace: free_space=%s freespace_ok=%d free_space_errno=%d have_media=%d\n",
614 edit_uint64(free_space, ed1), !!is_freespace_ok(), free_space_errno, !!have_media());
618 icmd = device->free_space_command;
621 set_freespace(0, 0, 0, false);
622 Dmsg2(20, "ERROR: update_free_space_dev: free_space=%s, free_space_errno=%d (!icmd)\n",
623 edit_uint64(free_space, ed1), free_space_errno);
624 Mmsg(errmsg, _("No FreeSpace command defined.\n"));
628 edit_mount_codes(ocmd, icmd);
630 Dmsg1(20, "update_freespace: cmd=%s\n", ocmd.c_str());
632 results = get_pool_memory(PM_MESSAGE);
634 Dmsg1(20, "Run freespace prog=%s\n", ocmd.c_str());
635 status = run_program_full_output(ocmd.c_str(), max_open_wait/2, results);
636 Dmsg2(20, "Freespace status=%d result=%s\n", status, results);
637 /* Should report "1223232 12323232\n" "free total\n" */
639 free = str_to_int64(results) * 1024;
642 if (skip_nonspaces(&p)) {
643 total = str_to_int64(p) * 1024;
649 Dmsg1(400, "Free space program run: Freespace=%s\n", results);
651 set_freespace(free, total, 0, true); /* have valid freespace */
656 set_freespace(0, 0, EPIPE, false); /* no valid freespace */
657 Mmsg2(errmsg, _("Cannot run free space command. Results=%s ERR=%s\n"),
658 results, be.bstrerror(status));
660 dev_errno = free_space_errno;
661 Dmsg4(20, "Cannot get free space on device %s. free_space=%s, "
662 "free_space_errno=%d ERR=%s\n",
663 print_name(), edit_uint64(free_space, ed1),
664 free_space_errno, errmsg);
666 free_pool_memory(results);
667 Dmsg4(20, "leave update_freespace: free_space=%s freespace_ok=%d free_space_errno=%d have_media=%d\n",
668 edit_uint64(free_space, ed1), !!is_freespace_ok(), free_space_errno, !!have_media());
672 void DEVICE::updateVolCatBytes(uint64_t bytes)
676 dev->VolCatInfo.VolCatAmetaBytes += bytes;
677 Dmsg1(200, "updateVolBytes ameta=%lld\n",
678 dev->VolCatInfo.VolCatAmetaBytes);
679 dev->VolCatInfo.VolCatBytes += bytes;
680 setVolCatInfo(false);
684 void DEVICE::updateVolCatBlocks(uint32_t blocks)
688 dev->VolCatInfo.VolCatAmetaBlocks += blocks;
689 dev->VolCatInfo.VolCatBlocks += blocks;
690 setVolCatInfo(false);
695 void DEVICE::updateVolCatWrites(uint32_t writes)
699 dev->VolCatInfo.VolCatAmetaWrites += writes;
700 dev->VolCatInfo.VolCatWrites += writes;
701 setVolCatInfo(false);
705 void DEVICE::updateVolCatReads(uint32_t reads)
709 dev->VolCatInfo.VolCatAmetaReads += reads;
710 dev->VolCatInfo.VolCatReads += reads;
711 setVolCatInfo(false);
715 void DEVICE::updateVolCatReadBytes(uint64_t bytes)
719 dev->VolCatInfo.VolCatAmetaRBytes += bytes;
720 dev->VolCatInfo.VolCatRBytes += bytes;
721 setVolCatInfo(false);
732 Dmsg4(40, "close_dev vol=%s fd=%d dev=%p dev=%s\n",
733 VolHdr.VolumeName, m_fd, this, print_name());
737 Dmsg2(200, "device %s already closed vol=%s\n", print_name(),
739 return true; /* already closed */
747 /* Fall through wanted */
749 if (d_close(m_fd) != 0) {
752 Mmsg2(errmsg, _("Error closing device %s. ERR=%s.\n"),
753 print_name(), be.bstrerror());
759 unmount(1); /* do unmount if required */
761 /* Clean up device packet so it can be reused */
765 * Be careful not to clear items needed by the DVD driver
766 * when it is closing a single part.
768 state &= ~(ST_LABEL|ST_READ|ST_APPEND|ST_EOT|ST_WEOT|ST_EOF|
769 ST_NOSPACE|ST_MOUNTED|ST_MEDIA|ST_SHORT);
770 label_type = B_BACULA_LABEL;
771 file = block_num = 0;
774 EndFile = EndBlock = 0;
777 memset(&VolCatInfo, 0, sizeof(VolCatInfo));
779 stop_thread_timer(tid);
786 * This call closes the device, but it is used in DVD handling
787 * where we close one part and then open the next part. The
788 * difference between close_part() and close() is that close_part()
789 * saves the state information of the device (e.g. the Volume lable,
790 * the Volume Catalog record, ... This permits opening and closing
791 * the Volume parts multiple times without losing track of what the
792 * main Volume parameters are.
794 void DEVICE::close_part(DCR * /*dcr*/)
796 VOLUME_LABEL saveVolHdr;
797 VOLUME_CAT_INFO saveVolCatInfo; /* Volume Catalog Information */
800 saveVolHdr = VolHdr; /* structure assignment */
801 saveVolCatInfo = VolCatInfo; /* structure assignment */
802 close(); /* close current part */
803 VolHdr = saveVolHdr; /* structure assignment */
804 VolCatInfo = saveVolCatInfo; /* structure assignment */
808 * If timeout, wait until the mount command returns 0.
809 * If !timeout, try to mount the device only once.
811 bool DEVICE::mount(int timeout)
813 Dmsg0(190, "Enter mount\n");
814 if (!is_mounted() && device->mount_command) {
815 return mount_file(1, timeout);
822 * If timeout, wait until the unmount command returns 0.
823 * If !timeout, try to unmount the device only once.
825 bool DEVICE::unmount(int timeout)
827 Dmsg0(100, "Enter unmount\n");
828 if (is_mounted() && requires_mount() && device->unmount_command) {
829 return mount_file(0, timeout);
836 * Edit codes into (Un)MountCommand, Write(First)PartCommand
838 * %a = archive device name
839 * %e = erase (set if cannot mount and first part)
842 * %v = last part name
844 * omsg = edited output message
845 * imsg = input string containing edit codes (%x)
848 void DEVICE::edit_mount_codes(POOL_MEM &omsg, const char *imsg)
854 POOL_MEM archive_name(PM_FNAME);
857 Dmsg1(800, "edit_mount_codes: %s\n", imsg);
858 for (p=imsg; *p; p++) {
868 if (num_dvd_parts == 0) {
869 if (truncating || blank_dvd) {
879 bsnprintf(add, sizeof(add), "%d", part);
883 str = device->mount_point;
897 Dmsg1(1900, "add_str %s\n", str);
898 pm_strcat(omsg, (char *)str);
899 Dmsg1(1800, "omsg=%s\n", omsg.c_str());
903 /* return the last timer interval (ms)
904 * or 0 if something goes wrong
906 btime_t DEVICE::get_timer_count()
908 btime_t temp = last_timer;
909 last_timer = get_current_btime();
910 temp = last_timer - temp; /* get elapsed time */
911 return (temp>0)?temp:0; /* take care of skewed clock */
915 ssize_t DEVICE::read(void *buf, size_t len)
921 read_len = d_read(m_fd, buf, len);
923 last_tick = get_timer_count();
925 DevReadTime += last_tick;
926 VolCatInfo.VolReadTime += last_tick;
928 if (read_len > 0) { /* skip error */
929 DevReadBytes += read_len;
936 ssize_t DEVICE::write(const void *buf, size_t len)
942 write_len = d_write(m_fd, buf, len);
944 last_tick = get_timer_count();
946 DevWriteTime += last_tick;
947 VolCatInfo.VolWriteTime += last_tick;
949 if (write_len > 0) { /* skip error */
950 DevWriteBytes += write_len;
956 /* Return the resource name for the device */
957 const char *DEVICE::name() const
959 return device->hdr.name;
962 uint32_t DEVICE::get_file()
964 if (is_dvd() || is_tape()) {
967 uint64_t bytes = VolCatInfo.VolCatAdataBytes + VolCatInfo.VolCatAmetaBytes;
968 return (uint32_t)(bytes >> 32);
972 uint32_t DEVICE::get_block_num()
974 if (is_dvd() || is_tape()) {
977 return VolCatInfo.VolCatAdataBlocks + VolCatInfo.VolCatAmetaBlocks;
982 * Walk through all attached jcrs indicating the volume has changed
983 * Note: If you have the new VolumeName, it is passed here,
984 * otherwise pass a NULL.
987 DEVICE::notify_newvol_in_attached_dcrs(const char *newVolumeName)
989 Dmsg2(140, "Notify dcrs of vol change. oldVolume=%s NewVolume=%s\n",
990 getVolCatName(), newVolumeName?"*None*":newVolumeName);
993 foreach_dlist(mdcr, attached_dcrs) {
994 if (mdcr->jcr->JobId == 0) {
995 continue; /* ignore console */
998 mdcr->NewFile = true;
999 if (newVolumeName && mdcr->VolumeName != newVolumeName) {
1000 bstrncpy(mdcr->VolumeName, newVolumeName, sizeof(mdcr->VolumeName));
1001 Dmsg2(140, "Set NewVol=%s in JobId=%d\n", mdcr->VolumeName, mdcr->jcr->JobId);
1008 * Walk through all attached jcrs indicating the File has changed
1011 DEVICE::notify_newfile_in_attached_dcrs()
1013 Dmsg1(140, "Notify dcrs of file change. Volume=%s\n", getVolCatName());
1016 foreach_dlist(mdcr, attached_dcrs) {
1017 if (mdcr->jcr->JobId == 0) {
1018 continue; /* ignore console */
1020 Dmsg1(140, "Notify JobI=%d\n", mdcr->jcr->JobId);
1021 mdcr->NewFile = true;
1029 * Free memory allocated for the device
1031 void DEVICE::term(void)
1034 Dmsg1(900, "term dev: %s\n", print_name());
1037 free_memory(dev_name);
1041 free_memory(prt_name);
1045 free_pool_memory(errmsg);
1048 pthread_mutex_destroy(&m_mutex);
1049 pthread_cond_destroy(&wait);
1050 pthread_cond_destroy(&wait_next_vol);
1051 pthread_mutex_destroy(&spool_mutex);
1052 pthread_mutex_destroy(&freespace_mutex);
1053 if (attached_dcrs) {
1054 delete attached_dcrs;
1055 attached_dcrs = NULL;
1057 /* We let the DEVRES pointer if not our device */
1058 if (device && device->dev == this) {
1067 /* Get freespace values */
1068 void DEVICE::get_freespace(uint64_t *freeval, uint64_t *totalval)
1070 get_os_device_freespace();
1072 if (is_freespace_ok()) {
1073 *freeval = free_space;
1074 *totalval = total_space;
1076 *freeval = *totalval = 0;
1081 /* Set freespace values */
1082 void DEVICE::set_freespace(uint64_t freeval, uint64_t totalval, int errnoval, bool valid)
1085 free_space = freeval;
1086 total_space = totalval;
1087 free_space_errno = errnoval;
1091 clear_freespace_ok();
1097 * This routine initializes the device wait timers
1099 void init_device_wait_timers(DCR *dcr)
1101 DEVICE *dev = dcr->dev;
1102 JCR *jcr = dcr->jcr;
1104 /* ******FIXME******* put these on config variables */
1105 dev->min_wait = 60 * 60;
1106 dev->max_wait = 24 * 60 * 60;
1107 dev->max_num_wait = 9; /* 5 waits =~ 1 day, then 1 day at a time */
1108 dev->wait_sec = dev->min_wait;
1109 dev->rem_wait_sec = dev->wait_sec;
1113 jcr->min_wait = 60 * 60;
1114 jcr->max_wait = 24 * 60 * 60;
1115 jcr->max_num_wait = 9; /* 5 waits =~ 1 day, then 1 day at a time */
1116 jcr->wait_sec = jcr->min_wait;
1117 jcr->rem_wait_sec = jcr->wait_sec;
1122 void init_jcr_device_wait_timers(JCR *jcr)
1124 /* ******FIXME******* put these on config variables */
1125 jcr->min_wait = 60 * 60;
1126 jcr->max_wait = 24 * 60 * 60;
1127 jcr->max_num_wait = 9; /* 5 waits =~ 1 day, then 1 day at a time */
1128 jcr->wait_sec = jcr->min_wait;
1129 jcr->rem_wait_sec = jcr->wait_sec;
1135 * The dev timers are used for waiting on a particular device
1137 * Returns: true if time doubled
1138 * false if max time expired
1140 bool double_dev_wait_time(DEVICE *dev)
1142 dev->wait_sec *= 2; /* double wait time */
1143 if (dev->wait_sec > dev->max_wait) { /* but not longer than maxtime */
1144 dev->wait_sec = dev->max_wait;
1147 dev->rem_wait_sec = dev->wait_sec;
1148 if (dev->num_wait >= dev->max_num_wait) {
1154 static const char *modes[] = {
1155 "CREATE_READ_WRITE",
1162 const char *mode_to_str(int mode)
1164 static char buf[100];
1165 if (mode < 1 || mode > 4) {
1166 bsnprintf(buf, sizeof(buf), "BAD mode=%d", mode);
1169 return modes[mode-1];