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_freespace_mutex()) != 0) {
312 dev->dev_errno = errstat;
313 Mmsg1(dev->errmsg, _("Unable to init freespace mutex: ERR=%s\n"), be.bstrerror(errstat));
314 Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
316 if ((errstat = dev->init_read_acquire_mutex()) != 0) {
318 dev->dev_errno = errstat;
319 Mmsg1(dev->errmsg, _("Unable to init read acquire mutex: ERR=%s\n"), be.bstrerror(errstat));
320 Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
322 if ((errstat = dev->init_volcat_mutex()) != 0) {
324 dev->dev_errno = errstat;
325 Mmsg1(dev->errmsg, _("Unable to init volcat mutex: ERR=%s\n"), be.bstrerror(errstat));
326 Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
328 if ((errstat = dev->init_dcrs_mutex()) != 0) {
330 dev->dev_errno = errstat;
331 Mmsg1(dev->errmsg, _("Unable to init dcrs mutex: ERR=%s\n"), be.bstrerror(errstat));
332 Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
335 dev->set_mutex_priorities();
338 if ((errstat = rwl_init(&dev->lock)) != 0) {
340 dev->dev_errno = errstat;
341 Mmsg1(dev->errmsg, _("Unable to init mutex: ERR=%s\n"), be.bstrerror(errstat));
342 Jmsg0(jcr, M_ERROR_TERM, 0, dev->errmsg);
347 dev->attached_dcrs = New(dlist(dcr, &dcr->dev_link));
348 Dmsg2(100, "init_dev: tape=%d dev_name=%s\n", dev->is_tape(), dev->dev_name);
349 dev->initiated = true;
355 * Open the device with the operating system and
356 * initialize buffer pointers.
358 * Returns: true on success
361 * Note, for a tape, the VolName is the name we give to the
362 * volume (not really used here), but for a file, the
363 * VolName represents the name of the file to be created/opened.
364 * In the case of a file, the full name is the device name
365 * (archive_name) with the VolName concatenated.
367 bool DEVICE::open(DCR *dcr, int omode)
371 if (openmode == omode) {
374 Dmsg1(200, "Close fd=%d for mode change in open().\n", m_fd);
377 preserve = state & (ST_LABEL|ST_APPEND|ST_READ);
381 dcr->setVolCatName(dcr->VolumeName);
382 VolCatInfo = dcr->VolCatInfo; /* structure assign */
385 state &= ~(ST_NOSPACE|ST_LABEL|ST_APPEND|ST_READ|ST_EOT|ST_WEOT|ST_EOF);
386 label_type = B_BACULA_LABEL;
388 if (is_tape() || is_fifo()) {
389 open_tape_device(dcr, omode);
390 } else if (is_ftp()) {
391 open_device(dcr, omode);
393 Dmsg1(100, "call open_file_device mode=%s\n", mode_to_str(omode));
394 open_file_device(dcr, omode);
396 state |= preserve; /* reset any important state info */
397 Dmsg2(100, "preserve=0x%x fd=%d\n", preserve, m_fd);
399 Dmsg7(100, "open dev: fd=%d dev=%p dcr=%p vol=%s type=%d dev_name=%s mode=%s\n",
400 m_fd, getVolCatName(), this, dcr, dev_type, print_name(), mode_to_str(omode));
404 void DEVICE::set_mode(int new_mode)
407 case CREATE_READ_WRITE:
408 mode = O_CREAT | O_RDWR | O_BINARY;
410 case OPEN_READ_WRITE:
411 mode = O_RDWR | O_BINARY;
414 mode = O_RDONLY | O_BINARY;
416 case OPEN_WRITE_ONLY:
417 mode = O_WRONLY | O_BINARY;
420 Emsg0(M_ABORT, 0, _("Illegal mode given to open dev.\n"));
425 void DEVICE::open_device(DCR *dcr, int omode)
427 /* do nothing waiting to split open_file/tape_device */
432 * Called to indicate that we have just read an
433 * EOF from the device.
435 void DEVICE::set_ateof()
447 * Called to indicate we are now at the end of the tape, and
448 * writing is not possible.
450 void DEVICE::set_ateot()
452 /* Make tape effectively read-only */
453 Dmsg0(200, "==== Set AtEof\n");
454 state |= (ST_EOF|ST_EOT|ST_WEOT);
460 * Set the position of the device -- only for files and DVD
461 * For other devices, there is no generic way to do it.
462 * Returns: true on succes
465 bool DEVICE::update_pos(DCR *dcr)
472 Mmsg0(errmsg, _("Bad device call. Device not open\n"));
473 Emsg1(M_FATAL, 0, "%s", errmsg);
480 pos = lseek(dcr, (boffset_t)0, SEEK_CUR);
484 Pmsg1(000, _("Seek error: ERR=%s\n"), be.bstrerror());
485 Mmsg2(errmsg, _("lseek error on %s. ERR=%s.\n"),
486 print_name(), be.bstrerror());
490 block_num = (uint32_t)pos;
491 file = (uint32_t)(pos >> 32);
497 void DEVICE::set_slot(int32_t slot)
500 if (vol) vol->clear_slot();
503 void DEVICE::clear_slot()
506 if (vol) vol->set_slot(-1);
509 const char *DEVICE::print_type() const
511 return prt_dev_types[device->dev_type];
515 * Set to unload the current volume in the drive
517 void DEVICE::set_unload()
519 if (!m_unload && VolHdr.VolumeName[0] != 0) {
521 memcpy(UnloadVolName, VolHdr.VolumeName, sizeof(UnloadVolName));
522 notify_newvol_in_attached_dcrs(NULL);
527 * Clear volume header
529 void DEVICE::clear_volhdr()
531 Dmsg1(100, "Clear volhdr vol=%s\n", VolHdr.VolumeName);
532 memset(&VolHdr, 0, sizeof(VolHdr));
533 setVolCatInfo(false);
536 void DEVICE::set_nospace()
541 void DEVICE::clear_nospace()
543 state &= ~ST_NOSPACE;
546 /* Put device in append mode */
547 void DEVICE::set_append()
549 state &= ~(ST_NOSPACE|ST_READ|ST_EOT|ST_EOF|ST_WEOT); /* remove EOF/EOT flags */
553 /* Clear append mode */
554 void DEVICE::clear_append()
559 /* Put device in read mode */
560 void DEVICE::set_read()
562 state &= ~(ST_APPEND|ST_EOT|ST_EOF|ST_WEOT); /* remove EOF/EOT flags */
566 /* Clear read mode */
567 void DEVICE::clear_read()
573 * Get freespace using OS calls
574 * TODO: See if it's working with mount commands
576 bool DEVICE::get_os_device_freespace()
578 int64_t freespace, totalspace;
583 if (fs_get_free_space(dev_name, &freespace, &totalspace) == 0) {
584 set_freespace(freespace, totalspace, 0, true);
589 set_freespace(0, 0, 0, false); /* No valid freespace */
594 /* Update the free space on the device */
595 bool DEVICE::update_freespace()
597 POOL_MEM ocmd(PM_FNAME);
601 uint64_t free, total;
612 /* The device must be mounted in order for freespace to work */
613 if (requires_mount()) {
617 if (get_os_device_freespace()) {
618 Dmsg4(20, "get_os_device_freespace: free_space=%s freespace_ok=%d free_space_errno=%d have_media=%d\n",
619 edit_uint64(free_space, ed1), !!is_freespace_ok(), free_space_errno, !!have_media());
623 icmd = device->free_space_command;
626 set_freespace(0, 0, 0, false);
627 Dmsg2(20, "ERROR: update_free_space_dev: free_space=%s, free_space_errno=%d (!icmd)\n",
628 edit_uint64(free_space, ed1), free_space_errno);
629 Mmsg(errmsg, _("No FreeSpace command defined.\n"));
633 edit_mount_codes(ocmd, icmd);
635 Dmsg1(20, "update_freespace: cmd=%s\n", ocmd.c_str());
637 results = get_pool_memory(PM_MESSAGE);
639 Dmsg1(20, "Run freespace prog=%s\n", ocmd.c_str());
640 status = run_program_full_output(ocmd.c_str(), max_open_wait/2, results);
641 Dmsg2(20, "Freespace status=%d result=%s\n", status, results);
642 /* Should report "1223232 12323232\n" "free total\n" */
644 free = str_to_int64(results) * 1024;
647 if (skip_nonspaces(&p)) {
648 total = str_to_int64(p) * 1024;
654 Dmsg1(400, "Free space program run: Freespace=%s\n", results);
656 set_freespace(free, total, 0, true); /* have valid freespace */
661 set_freespace(0, 0, EPIPE, false); /* no valid freespace */
662 Mmsg2(errmsg, _("Cannot run free space command. Results=%s ERR=%s\n"),
663 results, be.bstrerror(status));
665 dev_errno = free_space_errno;
666 Dmsg4(20, "Cannot get free space on device %s. free_space=%s, "
667 "free_space_errno=%d ERR=%s\n",
668 print_name(), edit_uint64(free_space, ed1),
669 free_space_errno, errmsg);
671 free_pool_memory(results);
672 Dmsg4(20, "leave update_freespace: free_space=%s freespace_ok=%d free_space_errno=%d have_media=%d\n",
673 edit_uint64(free_space, ed1), !!is_freespace_ok(), free_space_errno, !!have_media());
677 void DEVICE::updateVolCatBytes(uint64_t bytes)
681 dev->VolCatInfo.VolCatAmetaBytes += bytes;
682 Dmsg1(200, "updateVolBytes ameta=%lld\n",
683 dev->VolCatInfo.VolCatAmetaBytes);
684 dev->VolCatInfo.VolCatBytes += bytes;
685 setVolCatInfo(false);
689 void DEVICE::updateVolCatBlocks(uint32_t blocks)
693 dev->VolCatInfo.VolCatAmetaBlocks += blocks;
694 dev->VolCatInfo.VolCatBlocks += blocks;
695 setVolCatInfo(false);
700 void DEVICE::updateVolCatWrites(uint32_t writes)
704 dev->VolCatInfo.VolCatAmetaWrites += writes;
705 dev->VolCatInfo.VolCatWrites += writes;
706 setVolCatInfo(false);
710 void DEVICE::updateVolCatReads(uint32_t reads)
714 dev->VolCatInfo.VolCatAmetaReads += reads;
715 dev->VolCatInfo.VolCatReads += reads;
716 setVolCatInfo(false);
720 void DEVICE::updateVolCatReadBytes(uint64_t bytes)
724 dev->VolCatInfo.VolCatAmetaRBytes += bytes;
725 dev->VolCatInfo.VolCatRBytes += bytes;
726 setVolCatInfo(false);
737 Dmsg4(40, "close_dev vol=%s fd=%d dev=%p dev=%s\n",
738 VolHdr.VolumeName, m_fd, this, print_name());
742 Dmsg2(200, "device %s already closed vol=%s\n", print_name(),
744 return true; /* already closed */
752 /* Fall through wanted */
754 if (d_close(m_fd) != 0) {
757 Mmsg2(errmsg, _("Error closing device %s. ERR=%s.\n"),
758 print_name(), be.bstrerror());
764 unmount(1); /* do unmount if required */
766 /* Clean up device packet so it can be reused */
770 * Be careful not to clear items needed by the DVD driver
771 * when it is closing a single part.
773 state &= ~(ST_LABEL|ST_READ|ST_APPEND|ST_EOT|ST_WEOT|ST_EOF|
774 ST_NOSPACE|ST_MOUNTED|ST_MEDIA|ST_SHORT);
775 label_type = B_BACULA_LABEL;
776 file = block_num = 0;
779 EndFile = EndBlock = 0;
782 memset(&VolCatInfo, 0, sizeof(VolCatInfo));
784 stop_thread_timer(tid);
791 * This call closes the device, but it is used in DVD handling
792 * where we close one part and then open the next part. The
793 * difference between close_part() and close() is that close_part()
794 * saves the state information of the device (e.g. the Volume lable,
795 * the Volume Catalog record, ... This permits opening and closing
796 * the Volume parts multiple times without losing track of what the
797 * main Volume parameters are.
799 void DEVICE::close_part(DCR * /*dcr*/)
801 VOLUME_LABEL saveVolHdr;
802 VOLUME_CAT_INFO saveVolCatInfo; /* Volume Catalog Information */
805 saveVolHdr = VolHdr; /* structure assignment */
806 saveVolCatInfo = VolCatInfo; /* structure assignment */
807 close(); /* close current part */
808 VolHdr = saveVolHdr; /* structure assignment */
809 VolCatInfo = saveVolCatInfo; /* structure assignment */
813 * If timeout, wait until the mount command returns 0.
814 * If !timeout, try to mount the device only once.
816 bool DEVICE::mount(int timeout)
818 Dmsg0(190, "Enter mount\n");
819 if (!is_mounted() && device->mount_command) {
820 return mount_file(1, timeout);
827 * If timeout, wait until the unmount command returns 0.
828 * If !timeout, try to unmount the device only once.
830 bool DEVICE::unmount(int timeout)
832 Dmsg0(100, "Enter unmount\n");
833 if (is_mounted() && requires_mount() && device->unmount_command) {
834 return mount_file(0, timeout);
841 * Edit codes into (Un)MountCommand, Write(First)PartCommand
843 * %a = archive device name
844 * %e = erase (set if cannot mount and first part)
847 * %v = last part name
849 * omsg = edited output message
850 * imsg = input string containing edit codes (%x)
853 void DEVICE::edit_mount_codes(POOL_MEM &omsg, const char *imsg)
859 POOL_MEM archive_name(PM_FNAME);
862 Dmsg1(800, "edit_mount_codes: %s\n", imsg);
863 for (p=imsg; *p; p++) {
873 if (num_dvd_parts == 0) {
874 if (truncating || blank_dvd) {
884 bsnprintf(add, sizeof(add), "%d", part);
888 str = device->mount_point;
902 Dmsg1(1900, "add_str %s\n", str);
903 pm_strcat(omsg, (char *)str);
904 Dmsg1(1800, "omsg=%s\n", omsg.c_str());
908 /* return the last timer interval (ms)
909 * or 0 if something goes wrong
911 btime_t DEVICE::get_timer_count()
913 btime_t temp = last_timer;
914 last_timer = get_current_btime();
915 temp = last_timer - temp; /* get elapsed time */
916 return (temp>0)?temp:0; /* take care of skewed clock */
920 ssize_t DEVICE::read(void *buf, size_t len)
926 read_len = d_read(m_fd, buf, len);
928 last_tick = get_timer_count();
930 DevReadTime += last_tick;
931 VolCatInfo.VolReadTime += last_tick;
933 if (read_len > 0) { /* skip error */
934 DevReadBytes += read_len;
941 ssize_t DEVICE::write(const void *buf, size_t len)
947 write_len = d_write(m_fd, buf, len);
949 last_tick = get_timer_count();
951 DevWriteTime += last_tick;
952 VolCatInfo.VolWriteTime += last_tick;
954 if (write_len > 0) { /* skip error */
955 DevWriteBytes += write_len;
961 /* Return the resource name for the device */
962 const char *DEVICE::name() const
964 return device->hdr.name;
967 uint32_t DEVICE::get_file()
969 if (is_dvd() || is_tape()) {
972 uint64_t bytes = VolCatInfo.VolCatAdataBytes + VolCatInfo.VolCatAmetaBytes;
973 return (uint32_t)(bytes >> 32);
977 uint32_t DEVICE::get_block_num()
979 if (is_dvd() || is_tape()) {
982 return VolCatInfo.VolCatAdataBlocks + VolCatInfo.VolCatAmetaBlocks;
987 * Walk through all attached jcrs indicating the volume has changed
988 * Note: If you have the new VolumeName, it is passed here,
989 * otherwise pass a NULL.
992 DEVICE::notify_newvol_in_attached_dcrs(const char *newVolumeName)
994 Dmsg2(140, "Notify dcrs of vol change. oldVolume=%s NewVolume=%s\n",
995 getVolCatName(), newVolumeName?"*None*":newVolumeName);
998 foreach_dlist(mdcr, attached_dcrs) {
999 if (mdcr->jcr->JobId == 0) {
1000 continue; /* ignore console */
1002 mdcr->NewVol = true;
1003 mdcr->NewFile = true;
1004 if (newVolumeName && mdcr->VolumeName != newVolumeName) {
1005 bstrncpy(mdcr->VolumeName, newVolumeName, sizeof(mdcr->VolumeName));
1006 Dmsg2(140, "Set NewVol=%s in JobId=%d\n", mdcr->VolumeName, mdcr->jcr->JobId);
1013 * Walk through all attached jcrs indicating the File has changed
1016 DEVICE::notify_newfile_in_attached_dcrs()
1018 Dmsg1(140, "Notify dcrs of file change. Volume=%s\n", getVolCatName());
1021 foreach_dlist(mdcr, attached_dcrs) {
1022 if (mdcr->jcr->JobId == 0) {
1023 continue; /* ignore console */
1025 Dmsg1(140, "Notify JobI=%d\n", mdcr->jcr->JobId);
1026 mdcr->NewFile = true;
1034 * Free memory allocated for the device
1036 void DEVICE::term(void)
1039 Dmsg1(900, "term dev: %s\n", print_name());
1042 free_memory(dev_name);
1046 free_memory(prt_name);
1050 free_pool_memory(errmsg);
1053 pthread_mutex_destroy(&m_mutex);
1054 pthread_cond_destroy(&wait);
1055 pthread_cond_destroy(&wait_next_vol);
1056 pthread_mutex_destroy(&spool_mutex);
1057 pthread_mutex_destroy(&freespace_mutex);
1058 if (attached_dcrs) {
1059 delete attached_dcrs;
1060 attached_dcrs = NULL;
1062 /* We let the DEVRES pointer if not our device */
1063 if (device && device->dev == this) {
1072 /* Get freespace values */
1073 void DEVICE::get_freespace(uint64_t *freeval, uint64_t *totalval)
1075 get_os_device_freespace();
1077 if (is_freespace_ok()) {
1078 *freeval = free_space;
1079 *totalval = total_space;
1081 *freeval = *totalval = 0;
1086 /* Set freespace values */
1087 void DEVICE::set_freespace(uint64_t freeval, uint64_t totalval, int errnoval, bool valid)
1090 free_space = freeval;
1091 total_space = totalval;
1092 free_space_errno = errnoval;
1096 clear_freespace_ok();
1102 * This routine initializes the device wait timers
1104 void init_device_wait_timers(DCR *dcr)
1106 DEVICE *dev = dcr->dev;
1107 JCR *jcr = dcr->jcr;
1109 /* ******FIXME******* put these on config variables */
1110 dev->min_wait = 60 * 60;
1111 dev->max_wait = 24 * 60 * 60;
1112 dev->max_num_wait = 9; /* 5 waits =~ 1 day, then 1 day at a time */
1113 dev->wait_sec = dev->min_wait;
1114 dev->rem_wait_sec = dev->wait_sec;
1118 jcr->min_wait = 60 * 60;
1119 jcr->max_wait = 24 * 60 * 60;
1120 jcr->max_num_wait = 9; /* 5 waits =~ 1 day, then 1 day at a time */
1121 jcr->wait_sec = jcr->min_wait;
1122 jcr->rem_wait_sec = jcr->wait_sec;
1127 void init_jcr_device_wait_timers(JCR *jcr)
1129 /* ******FIXME******* put these on config variables */
1130 jcr->min_wait = 60 * 60;
1131 jcr->max_wait = 24 * 60 * 60;
1132 jcr->max_num_wait = 9; /* 5 waits =~ 1 day, then 1 day at a time */
1133 jcr->wait_sec = jcr->min_wait;
1134 jcr->rem_wait_sec = jcr->wait_sec;
1140 * The dev timers are used for waiting on a particular device
1142 * Returns: true if time doubled
1143 * false if max time expired
1145 bool double_dev_wait_time(DEVICE *dev)
1147 dev->wait_sec *= 2; /* double wait time */
1148 if (dev->wait_sec > dev->max_wait) { /* but not longer than maxtime */
1149 dev->wait_sec = dev->max_wait;
1152 dev->rem_wait_sec = dev->wait_sec;
1153 if (dev->num_wait >= dev->max_num_wait) {
1159 static const char *modes[] = {
1160 "CREATE_READ_WRITE",
1167 const char *mode_to_str(int mode)
1169 static char buf[100];
1170 if (mode < 1 || mode > 4) {
1171 bsnprintf(buf, sizeof(buf), "BAD mode=%d", mode);
1174 return modes[mode-1];