X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fstored%2Fdev.h;h=4516c626c90e3252583b050ec604b650d8b49f15;hb=1c31d780ff8befc9ef13c681d991bf235cb5f735;hp=7f9025ae5dddac73137a972c9029f6a3bbb04845;hpb=94210b670dbff54b7588cca047dcd8033820f01d;p=bacula%2Fbacula diff --git a/bacula/src/stored/dev.h b/bacula/src/stored/dev.h index 7f9025ae5d..4516c626c9 100644 --- a/bacula/src/stored/dev.h +++ b/bacula/src/stored/dev.h @@ -2,11 +2,13 @@ * Definitions for using the Device functions in Bacula * Tape and File storage access * + * Kern Sibbald, MM + * * Version $Id$ * */ /* - Copyright (C) 2000, 2001, 2002 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 @@ -29,6 +31,8 @@ #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)) @@ -40,65 +44,85 @@ #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 +enum { + OPEN_READ_WRITE = 0, + OPEN_READ_ONLY, + OPEN_WRITE_ONLY +}; /* Generic status bits returned from status_dev() */ -#define MT_TAPE (1<<0) /* is tape device */ -#define MT_EOF (1<<1) /* just read EOF */ -#define MT_BOT (1<<2) /* at beginning of tape */ -#define MT_EOT (1<<3) /* end of tape reached */ -#define MT_SM (1<<4) /* DDS setmark */ -#define MT_EOD (1<<5) /* DDS at end of data */ -#define MT_WR_PROT (1<<6) /* tape write protected */ -#define MT_ONLINE (1<<7) /* tape online */ -#define MT_DR_OPEN (1<<8) /* tape door open */ -#define MT_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 */ - - -/* Tape state bits */ -#define ST_OPENED 0x001 /* set when device opened */ -#define ST_TAPE 0x002 /* is a tape device */ -#define ST_LABEL 0x004 /* label found */ -#define ST_MALLOC 0x008 /* dev packet malloc'ed in init_dev() */ -#define ST_APPEND 0x010 /* ready for Bacula append */ -#define ST_READ 0x020 /* ready for Bacula read */ -#define ST_EOT 0x040 /* at end of tape */ -#define ST_WEOT 0x080 /* Got EOT on write */ -#define ST_EOF 0x100 /* Read EOF i.e. zero bytes */ -#define ST_NEXTVOL 0x200 /* Start writing on next volume */ -#define ST_SHORT 0x400 /* Short block read */ +#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, st_state) ((dev)->state & (st_state)) + +/* Device state bits */ +#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 */ +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 */ @@ -108,92 +132,133 @@ typedef struct s_volume_catalog_info { 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 */ - uint64_t VolCatMaxBytes; /* max bytes to write */ + 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 */ - void *attached_jcrs; /* attached JCR list */ -#ifdef NEW_LOCK - brwlock_t lock; /* new device locking mechanism */ -#endif +/* + * 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 */ - uint32_t file_bytes; /* bytes in this file */ - uint32_t LastBlockNumWritten; /* last block written */ + 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 */ uint32_t max_block_size; /* max block size */ - uint32_t max_volume_jobs; /* max jobs to put on one volume */ - uint64_t max_volume_files; /* max files to put on one volume */ 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 */ - void *device; /* pointer to Device Resource */ + uint32_t max_open_vols; /* max simultaneous open volumes */ + 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