* Definitions for using the Device functions in Bacula
* Tape and File storage access
*
+ * Kern Sibbald, MM
+ *
* Version $Id$
*
*/
/*
- Copyright (C) 2000-2003 Kern Sibbald and John Walker
+ Copyright (C) 2000-2004 Kern Sibbald and John Walker
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
#ifndef __DEV_H
#define __DEV_H 1
+#undef DCR /* used by Bacula */
+
/* #define NEW_LOCK 1 */
#define new_lock_device(dev) _new_lock_device(__FILE__, __LINE__, (dev))
#define block_device(d, s) _block_device(__FILE__, __LINE__, (d), s)
#define unblock_device(d) _unblock_device(__FILE__, __LINE__, (d))
#define steal_device_lock(d, p, s) _steal_device_lock(__FILE__, __LINE__, (d), (p), s)
-#define return_device_lock(d, p) _return_device_lock(__FILE__, __LINE__, (d), (p))
+#define give_back_device_lock(d, p) _give_back_device_lock(__FILE__, __LINE__, (d), (p))
/* Arguments to open_dev() */
-#define READ_WRITE 0
-#define READ_ONLY 1
-#define OPEN_READ_WRITE 0
-#define OPEN_READ_ONLY 1
-#define OPEN_WRITE_ONLY 2
+enum {
+ OPEN_READ_WRITE = 0,
+ OPEN_READ_ONLY,
+ OPEN_WRITE_ONLY
+};
/* Generic status bits returned from status_dev() */
-#define BMT_TAPE (1<<0) /* is tape device */
-#define BMT_EOF (1<<1) /* just read EOF */
-#define BMT_BOT (1<<2) /* at beginning of tape */
-#define BMT_EOT (1<<3) /* end of tape reached */
-#define BMT_SM (1<<4) /* DDS setmark */
-#define BMT_EOD (1<<5) /* DDS at end of data */
-#define BMT_WR_PROT (1<<6) /* tape write protected */
-#define BMT_ONLINE (1<<7) /* tape online */
-#define BMT_DR_OPEN (1<<8) /* tape door open */
-#define BMT_IM_REP_EN (1<<9) /* immediate report enabled */
+#define BMT_TAPE (1<<0) /* is tape device */
+#define BMT_EOF (1<<1) /* just read EOF */
+#define BMT_BOT (1<<2) /* at beginning of tape */
+#define BMT_EOT (1<<3) /* end of tape reached */
+#define BMT_SM (1<<4) /* DDS setmark */
+#define BMT_EOD (1<<5) /* DDS at end of data */
+#define BMT_WR_PROT (1<<6) /* tape write protected */
+#define BMT_ONLINE (1<<7) /* tape online */
+#define BMT_DR_OPEN (1<<8) /* tape door open */
+#define BMT_IM_REP_EN (1<<9) /* immediate report enabled */
/* Test capabilities */
#define dev_cap(dev, cap) ((dev)->capabilities & (cap))
/* Bits for device capabilities */
-#define CAP_EOF 0x0001 /* has MTWEOF */
-#define CAP_BSR 0x0002 /* has MTBSR */
-#define CAP_BSF 0x0004 /* has MTBSF */
-#define CAP_FSR 0x0008 /* has MTFSR */
-#define CAP_FSF 0x0010 /* has MTFSF */
-#define CAP_EOM 0x0020 /* has MTEOM */
-#define CAP_REM 0x0040 /* is removable media */
-#define CAP_RACCESS 0x0080 /* is random access device */
-#define CAP_AUTOMOUNT 0x0100 /* Read device at start to see what is there */
-#define CAP_LABEL 0x0200 /* Label blank tapes */
-#define CAP_ANONVOLS 0x0400 /* Mount without knowing volume name */
-#define CAP_ALWAYSOPEN 0x0800 /* always keep device open */
-#define CAP_AUTOCHANGER 0x1000 /* AutoChanger */
-#define CAP_OFFLINEUNMOUNT 0x2000 /* Offline before unmount */
-#define CAP_STREAM 0x4000 /* Stream device */
-#define CAP_BSFATEOM 0x8000 /* Backspace file at EOM */
+#define CAP_EOF (1<<0) /* has MTWEOF */
+#define CAP_BSR (1<<1) /* has MTBSR */
+#define CAP_BSF (1<<2) /* has MTBSF */
+#define CAP_FSR (1<<3) /* has MTFSR */
+#define CAP_FSF (1<<4) /* has MTFSF */
+#define CAP_EOM (1<<5) /* has MTEOM */
+#define CAP_REM (1<<6) /* is removable media */
+#define CAP_RACCESS (1<<7) /* is random access device */
+#define CAP_AUTOMOUNT (1<<8) /* Read device at start to see what is there */
+#define CAP_LABEL (1<<9) /* Label blank tapes */
+#define CAP_ANONVOLS (1<<10) /* Mount without knowing volume name */
+#define CAP_ALWAYSOPEN (1<<11) /* always keep device open */
+#define CAP_AUTOCHANGER (1<<12) /* AutoChanger */
+#define CAP_OFFLINEUNMOUNT (1<<13) /* Offline before unmount */
+#define CAP_STREAM (1<<14) /* Stream device */
+#define CAP_BSFATEOM (1<<15) /* Backspace file at EOM */
+#define CAP_FASTFSF (1<<16) /* Fast forward space file */
+#define CAP_TWOEOF (1<<17) /* Write two eofs for EOM */
+#define CAP_CLOSEONPOLL (1<<18) /* Close device on polling */
+#define CAP_POSITIONBLOCKS (1<<19) /* Use block positioning */
/* Test state */
-#define dev_state(dev, state) ((dev)->state & (state))
+#define dev_state(dev, st_state) ((dev)->state & (st_state))
/* Device state bits */
-#define ST_OPENED 0x0001 /* set when device opened */
-#define ST_TAPE 0x0002 /* is a tape device */
-#define ST_FILE 0x0004 /* is a file device */
-#define ST_FIFO 0x0008 /* is a fifo device */
-#define ST_PROG 0x0010 /* is a program device */
-#define ST_LABEL 0x0020 /* label found */
-#define ST_MALLOC 0x0040 /* dev packet malloc'ed in init_dev() */
-#define ST_APPEND 0x0080 /* ready for Bacula append */
-#define ST_READ 0x0100 /* ready for Bacula read */
-#define ST_EOT 0x0200 /* at end of tape */
-#define ST_WEOT 0x0400 /* Got EOT on write */
-#define ST_EOF 0x0800 /* Read EOF i.e. zero bytes */
-#define ST_NEXTVOL 0x1000 /* Start writing on next volume */
-#define ST_SHORT 0x2000 /* Short block read */
+#define ST_OPENED (1<<0) /* set when device opened */
+#define ST_TAPE (1<<1) /* is a tape device */
+#define ST_FILE (1<<2) /* is a file device */
+#define ST_FIFO (1<<3) /* is a fifo device */
+#define ST_PROG (1<<4) /* is a program device */
+#define ST_LABEL (1<<5) /* label found */
+#define ST_MALLOC (1<<6) /* dev packet malloc'ed in init_dev() */
+#define ST_APPEND (1<<7) /* ready for Bacula append */
+#define ST_READ (1<<8) /* ready for Bacula read */
+#define ST_EOT (1<<9) /* at end of tape */
+#define ST_WEOT (1<<10) /* Got EOT on write */
+#define ST_EOF (1<<11) /* Read EOF i.e. zero bytes */
+#define ST_NEXTVOL (1<<12) /* Start writing on next volume */
+#define ST_SHORT (1<<13) /* Short block read */
/* dev_blocked states (mutually exclusive) */
-#define BST_NOT_BLOCKED 0 /* not blocked */
-#define BST_UNMOUNTED 1 /* User unmounted device */
-#define BST_WAITING_FOR_SYSOP 2 /* Waiting for operator to mount tape */
-#define BST_DOING_ACQUIRE 3 /* Opening/validating/moving tape */
-#define BST_WRITING_LABEL 4 /* Labeling a tape */
-#define BST_UNMOUNTED_WAITING_FOR_SYSOP 5 /* Closed by user during mount request */
-#define BST_MOUNT 6 /* Mount request */
+enum {
+ BST_NOT_BLOCKED = 0, /* not blocked */
+ BST_UNMOUNTED, /* User unmounted device */
+ BST_WAITING_FOR_SYSOP, /* Waiting for operator to mount tape */
+ BST_DOING_ACQUIRE, /* Opening/validating/moving tape */
+ BST_WRITING_LABEL, /* Labeling a tape */
+ BST_UNMOUNTED_WAITING_FOR_SYSOP, /* Closed by user during mount request */
+ BST_MOUNT /* Mount request */
+};
/* Volume Catalog Information structure definition */
-typedef struct s_volume_catalog_info {
+struct VOLUME_CAT_INFO {
/* Media info for the current Volume */
uint32_t VolCatJobs; /* number of jobs on this Volume */
uint32_t VolCatFiles; /* Number of files */
uint32_t VolCatErrors; /* Number of errors this volume */
uint32_t VolCatWrites; /* Number of writes this volume */
uint32_t VolCatReads; /* Number of reads this volume */
+ uint64_t VolCatRBytes; /* Number of bytes read */
uint32_t VolCatRecycles; /* Number of recycles this volume */
int32_t Slot; /* Slot in changer */
+ bool InChanger; /* Set if vol in current magazine */
uint32_t VolCatMaxJobs; /* Maximum Jobs to write to volume */
uint32_t VolCatMaxFiles; /* Maximum files to write to volume */
uint64_t VolCatMaxBytes; /* Max bytes to write to volume */
uint64_t VolCatCapacityBytes; /* capacity estimate */
+ uint64_t VolReadTime; /* time spent reading */
+ uint64_t VolWriteTime; /* time spent writing this Volume */
char VolCatStatus[20]; /* Volume status */
char VolCatName[MAX_NAME_LENGTH]; /* Desired volume to mount */
-} VOLUME_CAT_INFO;
+};
typedef struct s_steal_lock {
- pthread_t no_wait_id; /* id of no wait thread */
- int dev_blocked; /* state */
+ pthread_t no_wait_id; /* id of no wait thread */
+ int dev_blocked; /* state */
+ int dev_prev_blocked; /* previous blocked state */
} bsteal_lock_t;
+struct DEVRES; /* Device resource defined in stored_conf.h */
-/* Device structure definition */
-typedef struct s_device {
- struct s_device *next; /* pointer to next open device */
- struct s_device *prev; /* pointer to prev open device */
- void *attached_jcrs; /* attached JCR list */
+/*
+ * Device structure definition. There is one of these for
+ * each physical device. Everything here is "global" to
+ * that device and effects all jobs using the device.
+ */
+struct DEVICE {
+public:
+ DEVICE *next; /* pointer to next open device */
+ DEVICE *prev; /* pointer to prev open device */
+ JCR *attached_jcrs; /* attached JCR list */
+ dlist *attached_dcrs; /* attached DCR list */
pthread_mutex_t mutex; /* access control */
+ pthread_mutex_t spool_mutex; /* mutex for updating spool_size */
pthread_cond_t wait; /* thread wait variable */
pthread_cond_t wait_next_vol; /* wait for tape to be mounted */
pthread_t no_wait_id; /* this thread must not wait */
int dev_blocked; /* set if we must wait (i.e. change tape) */
+ int dev_prev_blocked; /* previous blocked state */
int num_waiting; /* number of threads waiting */
int num_writers; /* number of writing threads */
+
+ /* New access control in process of being implemented */
+ brwlock_t lock; /* New mutual exclusion lock */
+
int use_count; /* usage count on this device */
int fd; /* file descriptor */
int capabilities; /* capabilities mask */
int state; /* state mask */
int dev_errno; /* Our own errno */
int mode; /* read/write modes */
- char *dev_name; /* device name */
+ uint32_t drive_index; /* Autochanger drive index */
+ POOLMEM *dev_name; /* device name */
char *errmsg; /* nicely edited error message */
uint32_t block_num; /* current block number base 0 */
uint32_t file; /* current file number base 0 */
uint64_t file_addr; /* Current file read/write address */
+ uint64_t file_size; /* Current file size */
uint32_t EndBlock; /* last block written */
uint32_t EndFile; /* last file written */
uint32_t min_block_size; /* min block size */
uint64_t max_volume_size; /* max bytes to put on one volume */
uint64_t max_file_size; /* max file size to put in one file on volume */
uint64_t volume_capacity; /* advisory capacity */
+ uint64_t max_spool_size; /* maximum spool file size */
+ uint64_t spool_size; /* curren spool size */
uint32_t max_rewind_wait; /* max secs to allow for rewind */
uint32_t max_open_wait; /* max secs to allow for open */
uint32_t max_open_vols; /* max simultaneous open volumes */
- void *device; /* pointer to Device Resource */
- btimer_id tid; /* timer id */
+ utime_t vol_poll_interval; /* interval between polling Vol mount */
+ DEVRES *device; /* pointer to Device Resource */
+ btimer_t *tid; /* timer id */
VOLUME_CAT_INFO VolCatInfo; /* Volume Catalog Information */
VOLUME_LABEL VolHdr; /* Actual volume label */
+
+ /* Device wait times ***FIXME*** look at durations */
+ char BadVolName[MAX_NAME_LENGTH]; /* Last wrong Volume mounted */
+ bool poll; /* set to poll Volume */
+ int min_wait;
+ int max_wait;
+ int max_num_wait;
+ int wait_sec;
+ int rem_wait_sec;
+ int num_wait;
+};
-} DEVICE;
-
-
-
-
-#ifdef SunOS
-#define DEFAULT_TAPE_DRIVE "/dev/rmt/0cbn"
-#endif
-#ifdef AIX
-#define DEFAULT_TAPE_DRIVE "/dev/rmt0.1"
-#endif
-#ifdef SGI
-#define DEFAULT_TAPE_DRIVE "/dev/tps0d4nr"
-#endif
-#ifdef Linux
-#define DEFAULT_TAPE_DRIVE "/dev/nst0"
-#endif
-#ifdef OSF
-#define DEFAULT_TAPE_DRIVE "/dev/nrmt0"
-#endif
-#ifdef HPUX
-#define DEFAULT_TAPE_DRIVE "/dev/rmt/0hnb"
-#endif
-#ifdef FreeBSD
-#define DEFAULT_TAPE_DRIVE "/dev/nrst0"
-#endif
+/*
+ * Device Context (or Control) Record.
+ * There is one of these records for each Job that is using
+ * the device. Items in this record are "local" to the Job and
+ * do not affect other Jobs.
+ */
+class DCR {
+public:
+ dlink dev_link; /* link to attach to dev */
+ JCR *jcr; /* pointer to JCR */
+ DEVICE *dev; /* pointer to device */
+ DEV_BLOCK *block; /* pointer to block */
+ DEV_RECORD *rec; /* pointer to record */
+ int spool_fd; /* fd if spooling */
+ bool spool_data; /* set to spool data */
+ bool spooling; /* set when actually spooling */
+ bool dev_locked; /* set if dev already locked */
+ bool NewVol; /* set if new Volume mounted */
+ bool WroteVol; /* set if Volume written */
+ bool NewFile; /* set when EOF written */
+ uint32_t VolFirstIndex; /* First file index this Volume */
+ uint32_t VolLastIndex; /* Last file index this Volume */
+ uint32_t FileIndex; /* Current File Index */
+ uint32_t EndFile; /* End file written */
+ uint32_t StartFile; /* Start write file */
+ uint32_t StartBlock; /* Start write block */
+ uint32_t EndBlock; /* Ending block written */
+ int64_t spool_size; /* Current spool size */
+ int64_t max_spool_size; /* Max job spool size */
+ char VolumeName[MAX_NAME_LENGTH]; /* Volume name */
+ char pool_name[MAX_NAME_LENGTH]; /* pool name */
+ char pool_type[MAX_NAME_LENGTH]; /* pool type */
+ char media_type[MAX_NAME_LENGTH]; /* media type */
+ char dev_name[MAX_NAME_LENGTH]; /* dev name */
+ VOLUME_CAT_INFO VolCatInfo; /* Catalog info for desired volume */
+};
-/* Default default */
-#ifndef DEFAULT_TAPE_DRIVE
-#define DEFAULT_TAPE_DRIVE "/dev/nst0"
-#endif
/* Get some definition of function to position
* to the end of the medium in MTEOM. System